{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "28fd5b27",
   "metadata": {},
   "source": [
    "# Global Forecasting Models: Independent multi-series forecasting\n",
    "\n",
    "[Univariate time series forecasting](../introduction-forecasting/introduction-forecasting.html) focuses on modeling a single time series as a linear or nonlinear function of its own past values (lags), using historical observations to predict future ones. \n",
    "\n",
    "**Global forecasting** builds a single predictive model that considers all time series simultaneously. This approach seeks to learn the shared patterns that underlie the different series, helping to reduce the influence of noise present in individual time series. It is computationally efficient, easier to maintain, and often yields more robust generalization across series.\n",
    "\n",
    "In **independent multi-series forecasting**, a single model is trained using all time series, but each series is treated independently—past values of one series are not used to predict another. Modeling them together is still beneficial when the series share similar temporal dynamics. For example, sales of products A and B in the same store may not be directly related, but both are influenced by the same underlying store-level patterns.\n",
    "\n",
    "<p style=\"text-align: center\">\n",
    "<img src=\"../img/forecaster_multi_series_train_matrix_diagram.png\" style=\"width: 700px\">\n",
    "<br>\n",
    "<font size=\"2.5\"> <i>Internal Forecaster transformation of two time series and an exogenous variable into the matrices needed to train a machine learning model in a multi-series context.</i></font>\n",
    "</p>\n",
    "\n",
    "To predict the next *n* steps, the strategy of [recursive multi-step forecasting](../introduction-forecasting/introduction-forecasting.html#recursive-multi-step-forecasting) is applied, with the only difference being that the series name for which to estimate the predictions needs to be indicated.\n",
    "\n",
    "<p style=\"text-align: center\">\n",
    "<img src=\"../img/forecaster_multi_series_prediction_diagram.png\" style=\"width: 700px\">\n",
    "<br>\n",
    "<font size=\"2.5\"> <i>Diagram of recursive forecasting with multiple independent time series.</i></font>\n",
    "</p>\n",
    "\n",
    "Using the <code>ForecasterRecursiveMultiSeries</code> it is possible to easily build machine learning models for **independent multi-series forecasting**."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c561e7a",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,184,212,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00b8d4; border-color: #00b8d4; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00b8d4;\"></i>\n",
    "    <b style=\"color: #00b8d4;\">&#9998 Note</b>\n",
    "</p>\n",
    "\n",
    "Skforecast offers additional approaches to building global forecasting models:\n",
    "\n",
    "<ul>\n",
    "    <li>\n",
    "    <a href=\"../user_guides/multi-series-with-different-length-and-different_exog.html\">Global Forecasting Models: Time series with different lengths and different exogenous variables</a>\n",
    "    </li>\n",
    "    <li>\n",
    "    <a href=\"../user_guides/dependent-multi-series-multivariate-forecasting.html\">Global Forecasting Models: Dependent multi-series forecasting (Multivariate forecasting)</a>\n",
    "    </li>\n",
    "    <li>\n",
    "    <a href=\"../user_guides/forecasting-with-deep-learning-rnn-lstm.html\">Global Forecasting Models: Forecasting with Deep Learning</a>\n",
    "    </li>\n",
    "</ul>\n",
    "\n",
    "\n",
    "To learn more about global forecasting models visit our examples:\n",
    "\n",
    "<ul>\n",
    "    <li>\n",
    "    <a href=\"https://www.cienciadedatos.net/documentos/py44-multi-series-forecasting-skforecast.html\">Global Forecasting Models: Multi-series forecasting with Python and skforecast</a>\n",
    "    </li>\n",
    "    <li>\n",
    "    <a href=\"https://www.cienciadedatos.net/documentos/py59-scalable-forecasting-models.html\">Scalable Forecasting: Modeling thousand time series with a single global model</a>\n",
    "    </li>\n",
    "    <li>\n",
    "    <a href=\"https://cienciadedatos.net/documentos/py53-global-forecasting-models\">Global Forecasting Models: Comparative Analysis of Single and Multi-Series Forecasting Modeling</a>\n",
    "    </li>\n",
    "    <li>\n",
    "    <a href=\"https://cienciadedatos.net/documentos/py54-forecasting-with-deep-learning\">Forecasting with Deep Learning</a>\n",
    "    </li>\n",
    "</ul>\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32da61d8",
   "metadata": {},
   "source": [
    "## Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "26ab328f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Libraries\n",
    "# ==============================================================================\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import StandardScaler, MinMaxScaler\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "from lightgbm import LGBMRegressor\n",
    "from skforecast.datasets import fetch_dataset\n",
    "from skforecast.preprocessing import (\n",
    "    reshape_series_wide_to_long,\n",
    "    reshape_series_long_to_dict, \n",
    "    RollingFeatures\n",
    ")\n",
    "from skforecast.recursive import ForecasterRecursiveMultiSeries\n",
    "from skforecast.model_selection import (\n",
    "    OneStepAheadFold,\n",
    "    TimeSeriesFold,\n",
    "    backtesting_forecaster_multiseries,\n",
    "    grid_search_forecaster_multiseries,\n",
    "    random_search_forecaster_multiseries,\n",
    "    bayesian_search_forecaster_multiseries\n",
    ")\n",
    "from skforecast.plot import set_dark_theme"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "77a4bb4b",
   "metadata": {},
   "source": [
    "## Input data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0474c878",
   "metadata": {},
   "source": [
    "The class <code>[ForecasterRecursiveMultiSeries](../api/forecasterrecursivemultiseries.html)</code> allows the simultaneous modeling of time series, which may have equal or varying lengths. Various input types are accepted:\n",
    "\n",
    "- If `series` is a **wide-format pandas DataFrame**, each column represents a different time series, and the index must be either a `DatetimeIndex` or a `RangeIndex` with frequency or step size, as appropriate\n",
    "\n",
    "- If `series` is a **long-format pandas DataFrame with a MultiIndex**, the first level of the index must contain the series IDs, and the second level must be a `DatetimeIndex` with the same frequency across all series.\n",
    "\n",
    "- If `series` is a **dictionary**, each key must be a series ID, and each value must be a named `pandas Series`. All series must have the same index, which must be either a `DatetimeIndex` or a `RangeIndex`, and they must share the same frequency or step size, as appropriate.\n",
    "\n",
    "| Series type            | Index requirements                                                      |\n",
    "|:----------------------:|:------------------------------------------------------------------------|\n",
    "| `Wide DataFrame`       | `pandas DatetimeIndex` or `RangeIndex` (all series same step/frequency) |\n",
    "| `MultiIndex DataFrame` | First level `series_id`, second `datetime` (pandas `DatetimeIndex`)     |\n",
    "| `dict`                 | `pandas DatetimeIndex` or `RangeIndex` (all series same step/frequency) |\n",
    "\n",
    "<br>\n",
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,191,191,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00bfa5; border-color: #00bfa5; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00bfa5;\"></i>\n",
    "    <b style=\"color: #00bfa5;\">&#128161 Tip</b>\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "In terms of performance, using a <code>dict</code> is more efficient than a <code>pandas DataFrame</code>, either wide or long format, especially for larger datasets. This is because dictionaries enable faster access and manipulation of individual time series, without the structural overhead associated with DataFrames.\n",
    "</p>\n",
    "\n",
    "</div>\n",
    "\n",
    "If your original data is not in the desired format, **skforecast** provides several utility functions to perform the necessary transformations:\n",
    "\n",
    "+ <code>[reshape_series_wide_to_long](../api/preprocessing.html#skforecast.preprocessing.preprocessing.reshape_series_wide_to_long)</code>: Converts a wide-format DataFrame into a **long-format DataFrame with a MultiIndex**, where the first level contains the series IDs and the second level contains a `DatetimeIndex`.\n",
    "\n",
    "+ <code>[reshape_series_long_to_dict](../api/preprocessing.html#skforecast.preprocessing.preprocessing.reshape_series_long_to_dict)</code>: Converts a long-format DataFrame with a MultiIndex into a **dictionary of pandas Series**, where the keys are the series IDs and the values are the Series with the same index as the original DataFrame."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "73fb38e9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">╭─────────────────────── <span style=\"font-weight: bold\">items_sales</span> ───────────────────────╮\n",
       "│ <span style=\"font-weight: bold\">Description:</span>                                              │\n",
       "│ Simulated time series for the sales of 3 different items. │\n",
       "│                                                           │\n",
       "│ <span style=\"font-weight: bold\">Source:</span>                                                   │\n",
       "│ Simulated data.                                           │\n",
       "│                                                           │\n",
       "│ <span style=\"font-weight: bold\">URL:</span>                                                      │\n",
       "│ https://raw.githubusercontent.com/skforecast/skforecast-  │\n",
       "│ datasets/main/data/simulated_items_sales.csv              │\n",
       "│                                                           │\n",
       "│ <span style=\"font-weight: bold\">Shape:</span> 1097 rows x 3 columns                              │\n",
       "╰───────────────────────────────────────────────────────────╯\n",
       "</pre>\n"
      ],
      "text/plain": [
       "╭─────────────────────── \u001b[1mitems_sales\u001b[0m ───────────────────────╮\n",
       "│ \u001b[1mDescription:\u001b[0m                                              │\n",
       "│ Simulated time series for the sales of 3 different items. │\n",
       "│                                                           │\n",
       "│ \u001b[1mSource:\u001b[0m                                                   │\n",
       "│ Simulated data.                                           │\n",
       "│                                                           │\n",
       "│ \u001b[1mURL:\u001b[0m                                                      │\n",
       "│ https://raw.githubusercontent.com/skforecast/skforecast-  │\n",
       "│ datasets/main/data/simulated_items_sales.csv              │\n",
       "│                                                           │\n",
       "│ \u001b[1mShape:\u001b[0m 1097 rows x 3 columns                              │\n",
       "╰───────────────────────────────────────────────────────────╯\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>item_1</th>\n",
       "      <th>item_2</th>\n",
       "      <th>item_3</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-01</th>\n",
       "      <td>8.253175</td>\n",
       "      <td>21.047727</td>\n",
       "      <td>19.429739</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-02</th>\n",
       "      <td>22.777826</td>\n",
       "      <td>26.578125</td>\n",
       "      <td>28.009863</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-03</th>\n",
       "      <td>27.549099</td>\n",
       "      <td>31.751042</td>\n",
       "      <td>32.078922</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               item_1     item_2     item_3\n",
       "date                                       \n",
       "2012-01-01   8.253175  21.047727  19.429739\n",
       "2012-01-02  22.777826  26.578125  28.009863\n",
       "2012-01-03  27.549099  31.751042  32.078922"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataFrame wide to long:\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>series_id</th>\n",
       "      <th>datetime</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">item_1</th>\n",
       "      <th>2012-01-01</th>\n",
       "      <td>8.253175</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-02</th>\n",
       "      <td>22.777826</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-03</th>\n",
       "      <td>27.549099</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                          value\n",
       "series_id datetime             \n",
       "item_1    2012-01-01   8.253175\n",
       "          2012-01-02  22.777826\n",
       "          2012-01-03  27.549099"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# DataFrame wide to long\n",
    "# ==============================================================================\n",
    "data = fetch_dataset(name=\"items_sales\")\n",
    "display(data.head(3))\n",
    "\n",
    "print(\"DataFrame wide to long:\")\n",
    "series_long = reshape_series_wide_to_long(data=data)\n",
    "display(series_long.head(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7516e830",
   "metadata": {},
   "source": [
    "The long format DataFrame have a `MultiIndex` with the first level containing the series ID, `'series_id'`, and the second level, `'datetime'`, containing a `DatetimeIndex` with the same frequency for each series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "30fb04a2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "MultiIndex([('item_1', '2012-01-01'),\n",
       "            ('item_1', '2012-01-02'),\n",
       "            ('item_1', '2012-01-03'),\n",
       "            ('item_1', '2012-01-04'),\n",
       "            ('item_1', '2012-01-05')],\n",
       "           names=['series_id', 'datetime'])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# MultiIndex\n",
    "# ==============================================================================\n",
    "series_long.index[:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ff33379",
   "metadata": {},
   "source": [
    "If you want to leverage the performance of a dictionary, you can use the function <code>[reshape_series_long_to_dict](../api/preprocessing.html#skforecast.preprocessing.preprocessing.reshape_series_long_to_dict)</code> to transform a long format DataFrame into a dictionary. The resulting dictionary will have the series ID as keys and the corresponding `pandas Series` as values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "b2e46f76",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>series_id</th>\n",
       "      <th>datetime</th>\n",
       "      <th>value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>item_1</td>\n",
       "      <td>2012-01-01</td>\n",
       "      <td>8.253175</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>item_1</td>\n",
       "      <td>2012-01-02</td>\n",
       "      <td>22.777826</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>item_1</td>\n",
       "      <td>2012-01-03</td>\n",
       "      <td>27.549099</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  series_id   datetime      value\n",
       "0    item_1 2012-01-01   8.253175\n",
       "1    item_1 2012-01-02  22.777826\n",
       "2    item_1 2012-01-03  27.549099"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DataFrame long to dict:\n",
      "\n",
      "dict_keys(['item_1', 'item_2', 'item_3'])\n",
      "\n",
      "2012-01-01     8.253175\n",
      "2012-01-02    22.777826\n",
      "2012-01-03    27.549099\n",
      "Freq: D, Name: item_1, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Load time series\n",
    "# ==============================================================================\n",
    "display(series_long.reset_index().head(3))\n",
    "\n",
    "print(\"DataFrame long to dict:\")\n",
    "print(\"\")\n",
    "series_dict = reshape_series_long_to_dict(\n",
    "    data      = series_long.reset_index(),\n",
    "    series_id = 'series_id',\n",
    "    index     = 'datetime',\n",
    "    values    = 'value',\n",
    "    freq      = 'D'\n",
    ")\n",
    "\n",
    "print(series_dict.keys())\n",
    "print(\"\")\n",
    "print(series_dict['item_1'].head(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6574926",
   "metadata": {},
   "source": [
    "These input formats can be used to train the <code>ForecasterRecursiveMultiSeries</code> class. In this guide, we will use a long format DataFrame with a MultiIndex as input data. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98363f4d",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,184,212,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00b8d4; border-color: #00b8d4; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00b8d4;\"></i>\n",
    "    <b style=\"color: #00b8d4;\">&#9998 Note</b>\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "When working with time series of different lengths and distinct exogenous variables, it is recommended to use both <code>series</code> and <code>exog</code> as dictionaries. This approach simplifies data management and reduces the likelihood of errors.\n",
    "\n",
    "For a detailed example, see the user guide <a href=\"../user_guides/multi-series-with-different-length-and-different_exog.html\">Global Forecasting Models: Time series with different lengths and different exogenous variables</a>.\n",
    "</p>\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "9eca9251",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-09-20T09:48:06.136685Z",
     "start_time": "2022-09-20T09:48:06.122785Z"
    }
   },
   "outputs": [],
   "source": [
    "# Split data into train-test\n",
    "# ==============================================================================\n",
    "end_train = '2014-07-15 23:59:00'\n",
    "series_long_train = series_long.loc[series_long.index.get_level_values('datetime') <= end_train, :].copy()\n",
    "series_long_test  = series_long.loc[series_long.index.get_level_values('datetime') > end_train, :].copy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "65e20a4d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "item_1:\n",
      "\tTrain: len=927, 2012-01-01 00:00:00 --- 2014-07-15 00:00:00\n",
      "\tTest : len=170, 2014-07-16 00:00:00 --- 2015-01-01 00:00:00\n",
      "item_2:\n",
      "\tTrain: len=927, 2012-01-01 00:00:00 --- 2014-07-15 00:00:00\n",
      "\tTest : len=170, 2014-07-16 00:00:00 --- 2015-01-01 00:00:00\n",
      "item_3:\n",
      "\tTrain: len=927, 2012-01-01 00:00:00 --- 2014-07-15 00:00:00\n",
      "\tTest : len=170, 2014-07-16 00:00:00 --- 2015-01-01 00:00:00\n"
     ]
    }
   ],
   "source": [
    "# Description of each partition\n",
    "# ==============================================================================\n",
    "for sid in series_long.index.levels[0]:\n",
    "    print(f\"{sid}:\")\n",
    "    try:\n",
    "        train_sub = series_long_train.loc[sid]\n",
    "        print(\n",
    "            f\"\\tTrain: len={len(train_sub)}, {train_sub.index[0]} --- {train_sub.index[-1]}\"\n",
    "        )\n",
    "    except IndexError:\n",
    "        print(\"\\tTrain: len=0\")\n",
    "    try:\n",
    "        test_sub = series_long_test.loc[sid]\n",
    "        print(\n",
    "            f\"\\tTest : len={len(test_sub)}, {test_sub.index[0]} --- {test_sub.index[-1]}\"\n",
    "        )\n",
    "    except IndexError:\n",
    "        print(\"\\tTest : len=0\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2c0ee344",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-09-20T09:48:45.616852Z",
     "start_time": "2022-09-20T09:48:45.150172Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 900x500 with 3 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot time series\n",
    "# ==============================================================================\n",
    "set_dark_theme()\n",
    "fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(9, 5), sharex=True)\n",
    "\n",
    "for i, sid in enumerate(series_long.index.levels[0]):\n",
    "    series_long_train.loc[sid, 'value'].plot(ax=axes[i], label='train')\n",
    "    series_long_test.loc[sid, 'value'].plot(ax=axes[i], label='test')\n",
    "    axes[i].set_title(sid)\n",
    "    axes[i].set_ylabel('sales')\n",
    "    axes[i].set_xlabel('')\n",
    "    axes[i].legend(loc='upper right')\n",
    "\n",
    "fig.tight_layout()\n",
    "plt.show();"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "9801a209-b601-4d9b-aa3c-a2e03df98c98",
   "metadata": {},
   "source": [
    "## ForecasterRecursiveMultiSeries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "349d1b95-5b16-4620-a46e-d595b4187ebe",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-09-20T09:59:14.441502Z",
     "start_time": "2022-09-20T09:59:14.404629Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭────────────────────────────────── InputTypeWarning ──────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Passing a DataFrame (either wide or long format) as `series` requires additional     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> internal transformations, which can increase computational time. It is recommended   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> to use a dictionary of pandas Series instead. For more details, see:                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> html#input-data                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.InputTypeWarning                                    <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:2349                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m InputTypeWarning \u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Passing a DataFrame (either wide or long format) as `series` requires additional     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m internal transformations, which can increase computational time. It is recommended   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m to use a dictionary of pandas Series instead. For more details, see:                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m html#input-data                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.InputTypeWarning                                    \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:2349                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "    <style>\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 {\n",
       "            font-family: 'Arial', sans-serif;\n",
       "            font-size: 0.9em;\n",
       "            color: #333333;\n",
       "            border: 1px solid #ddd;\n",
       "            background-color: #f0f8ff;\n",
       "            padding: 5px 15px;\n",
       "            border-radius: 8px;\n",
       "            max-width: 600px;\n",
       "            #margin: auto;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 h2 {\n",
       "            font-size: 1.5em;\n",
       "            color: #222222;\n",
       "            border-bottom: 2px solid #ddd;\n",
       "            padding-bottom: 5px;\n",
       "            margin-bottom: 15px;\n",
       "            margin-top: 5px;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 details {\n",
       "            margin: 10px 0;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 summary {\n",
       "            font-weight: bold;\n",
       "            font-size: 1.1em;\n",
       "            color: #000000;\n",
       "            cursor: pointer;\n",
       "            margin-bottom: 5px;\n",
       "            background-color: #b3dbfd;\n",
       "            padding: 5px;\n",
       "            border-radius: 5px;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 summary:hover {\n",
       "            color: #000000;\n",
       "            background-color: #e0e0e0;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 ul {\n",
       "            font-family: 'Courier New', monospace;\n",
       "            list-style-type: none;\n",
       "            padding-left: 20px;\n",
       "            margin: 10px 0;\n",
       "            line-height: normal;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 li {\n",
       "            margin: 5px 0;\n",
       "            font-family: 'Courier New', monospace;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 li strong {\n",
       "            font-weight: bold;\n",
       "            color: #444444;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 li::before {\n",
       "            content: \"- \";\n",
       "            color: #666666;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 a {\n",
       "            color: #001633;\n",
       "            text-decoration: none;\n",
       "        }\n",
       "        .container-941d6fda28af4effbaad6f11844da7a4 a:hover {\n",
       "            color: #359ccb; \n",
       "        }\n",
       "    </style>\n",
       "    \n",
       "        <div class=\"container-941d6fda28af4effbaad6f11844da7a4\">\n",
       "            <p style=\"font-size: 1.5em; font-weight: bold; margin-block-start: 0.83em; margin-block-end: 0.83em;\">ForecasterRecursiveMultiSeries</p>\n",
       "            <details open>\n",
       "                <summary>General Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Estimator:</strong> LGBMRegressor</li>\n",
       "                    <li><strong>Lags:</strong> [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]</li>\n",
       "                    <li><strong>Window features:</strong> ['roll_mean_24', 'roll_mean_48']</li>\n",
       "                    <li><strong>Window size:</strong> 48</li>\n",
       "                    <li><strong>Series encoding:</strong> ordinal</li>\n",
       "                    <li><strong>Exogenous included:</strong> False</li>\n",
       "                    <li><strong>Weight function included:</strong> False</li>\n",
       "                    <li><strong>Series weights:</strong> None</li>\n",
       "                    <li><strong>Differentiation order:</strong> None</li>\n",
       "                    <li><strong>Creation date:</strong> 2025-11-26 15:16:52</li>\n",
       "                    <li><strong>Last fit date:</strong> 2025-11-26 15:16:53</li>\n",
       "                    <li><strong>Skforecast version:</strong> 0.19.0</li>\n",
       "                    <li><strong>Python version:</strong> 3.12.11</li>\n",
       "                    <li><strong>Forecaster id:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Exogenous Variables</summary>\n",
       "                <ul>\n",
       "                    None\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Data Transformations</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Transformer for series:</strong> None</li>\n",
       "                    <li><strong>Transformer for exog:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Training Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Series names (levels):</strong> item_1, item_2, item_3</li>\n",
       "                    <li><strong>Training range:</strong> 'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'], 'item_3': ['2012-01-01', '2014-07-15']</li>\n",
       "                    <li><strong>Training index type:</strong> DatetimeIndex</li>\n",
       "                    <li><strong>Training index frequency:</strong> <Day></li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Estimator Parameters</summary>\n",
       "                <ul>\n",
       "                    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Fit Kwargs</summary>\n",
       "                <ul>\n",
       "                    {}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <p>\n",
       "                <a href=\"https://skforecast.org/0.19.0/api/forecasterrecursivemultiseries.html\">&#128712 <strong>API Reference</strong></a>\n",
       "                &nbsp;&nbsp;\n",
       "                <a href=\"https://skforecast.org/0.19.0/user_guides/independent-multi-time-series-forecasting.html\">&#128462 <strong>User Guide</strong></a>\n",
       "            </p>\n",
       "        </div>\n",
       "        "
      ],
      "text/plain": [
       "============================== \n",
       "ForecasterRecursiveMultiSeries \n",
       "============================== \n",
       "Estimator: LGBMRegressor \n",
       "Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] \n",
       "Window features: ['roll_mean_24', 'roll_mean_48'] \n",
       "Window size: 48 \n",
       "Series encoding: ordinal \n",
       "Series names (levels): item_1, item_2, item_3 \n",
       "Exogenous included: False \n",
       "Exogenous names: None \n",
       "Transformer for series: None \n",
       "Transformer for exog: None \n",
       "Weight function included: False \n",
       "Series weights: None \n",
       "Differentiation order: None \n",
       "Training range: \n",
       "    'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'],\n",
       "    'item_3': ['2012-01-01', '2014-07-15'] \n",
       "Training index type: DatetimeIndex \n",
       "Training index frequency: <Day> \n",
       "Estimator parameters: \n",
       "    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0,\n",
       "    'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1,\n",
       "    'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0,\n",
       "    'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None,\n",
       "    'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0,\n",
       "    'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1} \n",
       "fit_kwargs: {} \n",
       "Creation date: 2025-11-26 15:16:52 \n",
       "Last fit date: 2025-11-26 15:16:53 \n",
       "Skforecast version: 0.19.0 \n",
       "Python version: 3.12.11 \n",
       "Forecaster id: None "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create and train ForecasterRecursiveMultiSeries\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator          = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags               = 24,\n",
    "                 window_features    = RollingFeatures(stats=['mean', 'mean'], window_sizes=[24, 48]),\n",
    "                 encoding           = 'ordinal',\n",
    "                 transformer_series = None,\n",
    "                 transformer_exog   = None,\n",
    "                 weight_func        = None,\n",
    "                 series_weights     = None,\n",
    "                 differentiation    = None,\n",
    "                 dropna_from_series = False,\n",
    "                 fit_kwargs         = None,\n",
    "                 forecaster_id      = None\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train, store_in_sample_residuals=True)\n",
    "forecaster"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "be12a14b",
   "metadata": {},
   "source": [
    "Two methods can be use to predict the next n steps: `predict()` or `predict_interval()`. The argument `levels` is used to indicate for which series estimate predictions. If `None` all series will be predicted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f1bdf4f8-b999-4d97-899c-fbcc2af7066a",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-09-20T10:00:26.432022Z",
     "start_time": "2022-09-20T10:00:25.599841Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.698703</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.676440</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-18</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.269030</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_1  25.698703\n",
       "2014-07-17  item_1  25.676440\n",
       "2014-07-18  item_1  25.269030"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "      <th>lower_bound</th>\n",
       "      <th>upper_bound</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.698703</td>\n",
       "      <td>23.630908</td>\n",
       "      <td>27.766498</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>10.469603</td>\n",
       "      <td>8.967505</td>\n",
       "      <td>11.971702</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.676440</td>\n",
       "      <td>23.608645</td>\n",
       "      <td>27.744235</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred  lower_bound  upper_bound\n",
       "2014-07-16  item_1  25.698703    23.630908    27.766498\n",
       "2014-07-16  item_2  10.469603     8.967505    11.971702\n",
       "2014-07-17  item_1  25.676440    23.608645    27.744235"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Predictions and prediction intervals\n",
    "# ==============================================================================\n",
    "steps = 24\n",
    "\n",
    "# Predictions for item_1\n",
    "predictions_item_1 = forecaster.predict(steps=steps, levels='item_1')\n",
    "display(predictions_item_1.head(3))\n",
    "print(\"\")\n",
    "\n",
    "# Interval predictions for item_1 and item_2\n",
    "predictions_intervals = forecaster.predict_interval(\n",
    "    steps    = steps,\n",
    "    levels   = ['item_1', 'item_2'],\n",
    "    method   = \"conformal\",\n",
    "    interval = 0.9\n",
    ")\n",
    "display(predictions_intervals.head(3))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "bfc89fd7",
   "metadata": {},
   "source": [
    "## Backtesting multiple series\n",
    "\n",
    "As in the `predict` method, the `levels` at which [backtesting](../user_guides/backtesting.html) is performed must be indicated. The argument can also be set to `None` to perform backtesting at all levels. In addition to the individual metric(s) for each series, the aggregated value is calculated using the following methods:\n",
    "\n",
    "+ **average**: the average (arithmetic mean) of all levels.\n",
    "\n",
    "+ **weighted_average**: the average of the metrics weighted by the number of predicted values of each level.\n",
    "\n",
    "+ **pooling**: the values of all levels are pooled and then the metric is calculated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b1b53f4b-be13-4e7b-bfdd-2cf0f3492452",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2022-09-20T11:01:44.610083Z",
     "start_time": "2022-09-20T11:01:44.092807Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭────────────────────────────────── InputTypeWarning ──────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Passing a DataFrame (either wide or long format) as `series` requires additional     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> internal transformations, which can increase computational time. It is recommended   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> to use a dictionary of pandas Series instead. For more details, see:                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> html#input-data                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.InputTypeWarning                                    <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:2349                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m InputTypeWarning \u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Passing a DataFrame (either wide or long format) as `series` requires additional     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m internal transformations, which can increase computational time. It is recommended   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m to use a dictionary of pandas Series instead. For more details, see:                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m html#input-data                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.InputTypeWarning                                    \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:2349                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "200a8ef598574efcb99c8bc03aab0a3c",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/8 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Backtest metrics\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>levels</th>\n",
       "      <th>mean_absolute_error</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>item_1</td>\n",
       "      <td>1.194108</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>item_2</td>\n",
       "      <td>2.595094</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>item_3</td>\n",
       "      <td>3.316836</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>average</td>\n",
       "      <td>2.368679</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>weighted_average</td>\n",
       "      <td>2.368679</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>pooling</td>\n",
       "      <td>2.368679</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             levels  mean_absolute_error\n",
       "0            item_1             1.194108\n",
       "1            item_2             2.595094\n",
       "2            item_3             3.316836\n",
       "3           average             2.368679\n",
       "4  weighted_average             2.368679\n",
       "5           pooling             2.368679"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Backtest predictions\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>fold</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>0</td>\n",
       "      <td>25.698703</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>0</td>\n",
       "      <td>10.469603</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_3</td>\n",
       "      <td>0</td>\n",
       "      <td>11.329472</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_1</td>\n",
       "      <td>0</td>\n",
       "      <td>25.676440</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level  fold       pred\n",
       "2014-07-16  item_1     0  25.698703\n",
       "2014-07-16  item_2     0  10.469603\n",
       "2014-07-16  item_3     0  11.329472\n",
       "2014-07-17  item_1     0  25.676440"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Backtesting multiple time series\n",
    "# ==============================================================================\n",
    "cv = TimeSeriesFold(\n",
    "         steps              = 24,\n",
    "         initial_train_size = '2014-07-15 23:59:00',  # end_train\n",
    "         fold_stride        = None,\n",
    "         refit              = True\n",
    "     )\n",
    "\n",
    "metrics_levels, backtest_predictions = backtesting_forecaster_multiseries(\n",
    "    forecaster            = forecaster,\n",
    "    series                = series_long,\n",
    "    exog                  = None,\n",
    "    cv                    = cv,\n",
    "    levels                = None,\n",
    "    metric                = 'mean_absolute_error',\n",
    "    add_aggregated_metric = True\n",
    ")\n",
    "\n",
    "print(\"Backtest metrics\")\n",
    "display(metrics_levels)\n",
    "print(\"\")\n",
    "print(\"Backtest predictions\")\n",
    "backtest_predictions.head(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3222e83d",
   "metadata": {},
   "source": [
    "## Exogenous variables in multi-series forecasting\n",
    "\n",
    "Exogenous variables are predictors that are independent of the model being used for forecasting, and their future values must be known in order to include them in the prediction process. The class <code>[ForecasterRecursiveMultiSeries](../api/forecasterrecursivemultiseries.html)</code> supports multiple strategies for including exogenous variables:\n",
    "\n",
    "- If `exog` is a **wide-format pandas DataFrame**, it must share the same index type as series. Each column represents a different exogenous variable, and the same values are applied to all time series.\n",
    "\n",
    "- If `exog` is a **long-format pandas Series or DataFrame with a MultiIndex**, the first level contains the series IDs to which it belongs, and the second level must be a pandas `DatetimeIndex`. Each exogenous variable must be represented as a separate column.\n",
    "\n",
    "- If `exog` is a **dictionary**, each key must correspond to a series ID, and each value must be either a named pandas `Series` or `DataFrame` with the same index type as `series`, or `None`. It is not required for all series to contain all exogenous variables, but data types must be consistent across series for each variable.\n",
    "\n",
    "| Exog type              | Index requirements                                                      |\n",
    "|:----------------------:|:------------------------------------------------------------------------|\n",
    "| `Wide DataFrame`       | `pandas DatetimeIndex` or `RangeIndex` (all series same step/frequency) |\n",
    "| `MultiIndex DataFrame` | First level `series_id`, second `datetime` (pandas `DatetimeIndex`)     |\n",
    "| `dict`                 | `pandas DatetimeIndex` or `RangeIndex` (all series same step/frequency) |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1988d4a4",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,184,212,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00b8d4; border-color: #00b8d4; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00b8d4;\"></i>\n",
    "    <b style=\"color: #00b8d4;\">&#9998 Note</b>\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "    The <code>ForecasterRecursiveMultiSeries</code> supports the use of distinct exogenous variables for each individual series. For a comprehensive guide on handling time series with varying lengths and exogenous variables, refer to the \n",
    "    <a href=\"../user_guides/multi-series-with-different-length-and-different_exog.html\">Global Forecasting Models: Time Series with Different Lengths and Different Exogenous Variables</a>. \n",
    "    Additionally, for a more general overview of using exogenous variables in forecasting, please consult the \n",
    "    <a href=\"../user_guides/exogenous-variables.html\">Exogenous Variables User Guide</a>.\n",
    "</p>\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9e218c83",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>month</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>datetime</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-01</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-02</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-03</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            month\n",
       "datetime         \n",
       "2012-01-01      1\n",
       "2012-01-02      1\n",
       "2012-01-03      1"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Generate the exogenous variable month\n",
    "# ==============================================================================\n",
    "exog_wide = pd.DataFrame(\n",
    "    index = series_long.index.get_level_values('datetime').unique()\n",
    ")\n",
    "exog_wide['month'] = exog_wide.index.month\n",
    "\n",
    "# Split data into train-val-test\n",
    "# ==============================================================================\n",
    "end_train = '2014-07-15 23:59:00'\n",
    "exog_wide_train = exog_wide.loc[:end_train, :].copy()\n",
    "exog_wide_test  = exog_wide.loc[end_train:, :].copy()\n",
    "\n",
    "exog_wide_train.head(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8facf614",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭────────────────────────────────── InputTypeWarning ──────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Passing a DataFrame (either wide or long format) as `series` requires additional     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> internal transformations, which can increase computational time. It is recommended   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> to use a dictionary of pandas Series instead. For more details, see:                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> html#input-data                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.InputTypeWarning                                    <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:2349                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m InputTypeWarning \u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Passing a DataFrame (either wide or long format) as `series` requires additional     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m internal transformations, which can increase computational time. It is recommended   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m to use a dictionary of pandas Series instead. For more details, see:                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m html#input-data                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.InputTypeWarning                                    \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:2349                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "    <style>\n",
       "        .container-e3962dded3a64371acb516107ab57e76 {\n",
       "            font-family: 'Arial', sans-serif;\n",
       "            font-size: 0.9em;\n",
       "            color: #333333;\n",
       "            border: 1px solid #ddd;\n",
       "            background-color: #f0f8ff;\n",
       "            padding: 5px 15px;\n",
       "            border-radius: 8px;\n",
       "            max-width: 600px;\n",
       "            #margin: auto;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 h2 {\n",
       "            font-size: 1.5em;\n",
       "            color: #222222;\n",
       "            border-bottom: 2px solid #ddd;\n",
       "            padding-bottom: 5px;\n",
       "            margin-bottom: 15px;\n",
       "            margin-top: 5px;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 details {\n",
       "            margin: 10px 0;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 summary {\n",
       "            font-weight: bold;\n",
       "            font-size: 1.1em;\n",
       "            color: #000000;\n",
       "            cursor: pointer;\n",
       "            margin-bottom: 5px;\n",
       "            background-color: #b3dbfd;\n",
       "            padding: 5px;\n",
       "            border-radius: 5px;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 summary:hover {\n",
       "            color: #000000;\n",
       "            background-color: #e0e0e0;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 ul {\n",
       "            font-family: 'Courier New', monospace;\n",
       "            list-style-type: none;\n",
       "            padding-left: 20px;\n",
       "            margin: 10px 0;\n",
       "            line-height: normal;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 li {\n",
       "            margin: 5px 0;\n",
       "            font-family: 'Courier New', monospace;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 li strong {\n",
       "            font-weight: bold;\n",
       "            color: #444444;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 li::before {\n",
       "            content: \"- \";\n",
       "            color: #666666;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 a {\n",
       "            color: #001633;\n",
       "            text-decoration: none;\n",
       "        }\n",
       "        .container-e3962dded3a64371acb516107ab57e76 a:hover {\n",
       "            color: #359ccb; \n",
       "        }\n",
       "    </style>\n",
       "    \n",
       "        <div class=\"container-e3962dded3a64371acb516107ab57e76\">\n",
       "            <p style=\"font-size: 1.5em; font-weight: bold; margin-block-start: 0.83em; margin-block-end: 0.83em;\">ForecasterRecursiveMultiSeries</p>\n",
       "            <details open>\n",
       "                <summary>General Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Estimator:</strong> LGBMRegressor</li>\n",
       "                    <li><strong>Lags:</strong> [ 1  2  3  4  5  6  7  8  9 10 11 12]</li>\n",
       "                    <li><strong>Window features:</strong> ['roll_mean_24', 'roll_mean_48']</li>\n",
       "                    <li><strong>Window size:</strong> 48</li>\n",
       "                    <li><strong>Series encoding:</strong> ordinal</li>\n",
       "                    <li><strong>Exogenous included:</strong> True</li>\n",
       "                    <li><strong>Weight function included:</strong> False</li>\n",
       "                    <li><strong>Series weights:</strong> None</li>\n",
       "                    <li><strong>Differentiation order:</strong> None</li>\n",
       "                    <li><strong>Creation date:</strong> 2025-11-26 15:16:54</li>\n",
       "                    <li><strong>Last fit date:</strong> 2025-11-26 15:16:55</li>\n",
       "                    <li><strong>Skforecast version:</strong> 0.19.0</li>\n",
       "                    <li><strong>Python version:</strong> 3.12.11</li>\n",
       "                    <li><strong>Forecaster id:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Exogenous Variables</summary>\n",
       "                <ul>\n",
       "                    month\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Data Transformations</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Transformer for series:</strong> None</li>\n",
       "                    <li><strong>Transformer for exog:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Training Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Series names (levels):</strong> item_1, item_2, item_3</li>\n",
       "                    <li><strong>Training range:</strong> 'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'], 'item_3': ['2012-01-01', '2014-07-15']</li>\n",
       "                    <li><strong>Training index type:</strong> DatetimeIndex</li>\n",
       "                    <li><strong>Training index frequency:</strong> <Day></li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Estimator Parameters</summary>\n",
       "                <ul>\n",
       "                    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Fit Kwargs</summary>\n",
       "                <ul>\n",
       "                    {}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <p>\n",
       "                <a href=\"https://skforecast.org/0.19.0/api/forecasterrecursivemultiseries.html\">&#128712 <strong>API Reference</strong></a>\n",
       "                &nbsp;&nbsp;\n",
       "                <a href=\"https://skforecast.org/0.19.0/user_guides/independent-multi-time-series-forecasting.html\">&#128462 <strong>User Guide</strong></a>\n",
       "            </p>\n",
       "        </div>\n",
       "        "
      ],
      "text/plain": [
       "============================== \n",
       "ForecasterRecursiveMultiSeries \n",
       "============================== \n",
       "Estimator: LGBMRegressor \n",
       "Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12] \n",
       "Window features: ['roll_mean_24', 'roll_mean_48'] \n",
       "Window size: 48 \n",
       "Series encoding: ordinal \n",
       "Series names (levels): item_1, item_2, item_3 \n",
       "Exogenous included: True \n",
       "Exogenous names: month \n",
       "Transformer for series: None \n",
       "Transformer for exog: None \n",
       "Weight function included: False \n",
       "Series weights: None \n",
       "Differentiation order: None \n",
       "Training range: \n",
       "    'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'],\n",
       "    'item_3': ['2012-01-01', '2014-07-15'] \n",
       "Training index type: DatetimeIndex \n",
       "Training index frequency: <Day> \n",
       "Estimator parameters: \n",
       "    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0,\n",
       "    'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1,\n",
       "    'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0,\n",
       "    'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None,\n",
       "    'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0,\n",
       "    'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1} \n",
       "fit_kwargs: {} \n",
       "Creation date: 2025-11-26 15:16:54 \n",
       "Last fit date: 2025-11-26 15:16:55 \n",
       "Skforecast version: 0.19.0 \n",
       "Python version: 3.12.11 \n",
       "Forecaster id: None "
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create and fit forecaster\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator       = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags            = 12,\n",
    "                 window_features = RollingFeatures(stats=['mean', 'mean'], window_sizes=[24, 48]),\n",
    "                 encoding        = 'ordinal'\n",
    "             )\n",
    "\n",
    "forecaster.fit(\n",
    "    series = series_long_train, \n",
    "    exog   = exog_wide_train\n",
    ")\n",
    "forecaster"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3991a708",
   "metadata": {},
   "source": [
    "If the `Forecaster` has been trained using exogenous variables, they should be provided during the prediction phase."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "1ce6c1a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.609387</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>10.674722</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_3</td>\n",
       "      <td>11.716675</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_1  25.609387\n",
       "2014-07-16  item_2  10.674722\n",
       "2014-07-16  item_3  11.716675"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Predict with exogenous variables\n",
    "# ==============================================================================\n",
    "predictions = forecaster.predict(steps=24, exog=exog_wide_test)\n",
    "predictions.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f66bf3f6",
   "metadata": {},
   "source": [
    "As mentioned earlier, the `month` exogenous variable is replicated for each of the series. This can be easily demonstrated using the `create_train_X_y` method, which returns the matrix used in the `fit` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "38fb44e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# X_train matrix\n",
    "# ==============================================================================\n",
    "X_train = forecaster.create_train_X_y(\n",
    "              series            = series_long_train, \n",
    "              exog              = exog_wide_train,\n",
    "              suppress_warnings = True\n",
    "          )[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "3ea20fc1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>lag_4</th>\n",
       "      <th>lag_5</th>\n",
       "      <th>lag_6</th>\n",
       "      <th>lag_7</th>\n",
       "      <th>lag_8</th>\n",
       "      <th>lag_9</th>\n",
       "      <th>lag_10</th>\n",
       "      <th>lag_11</th>\n",
       "      <th>lag_12</th>\n",
       "      <th>roll_mean_24</th>\n",
       "      <th>roll_mean_48</th>\n",
       "      <th>_level_skforecast</th>\n",
       "      <th>month</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-02-18</th>\n",
       "      <td>25.609772</td>\n",
       "      <td>27.646380</td>\n",
       "      <td>25.061150</td>\n",
       "      <td>23.61924</td>\n",
       "      <td>20.78839</td>\n",
       "      <td>19.558775</td>\n",
       "      <td>22.208947</td>\n",
       "      <td>23.424717</td>\n",
       "      <td>22.807790</td>\n",
       "      <td>22.861086</td>\n",
       "      <td>23.008517</td>\n",
       "      <td>21.763739</td>\n",
       "      <td>23.796391</td>\n",
       "      <td>23.031106</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-02-19</th>\n",
       "      <td>22.504042</td>\n",
       "      <td>25.609772</td>\n",
       "      <td>27.646380</td>\n",
       "      <td>25.06115</td>\n",
       "      <td>23.61924</td>\n",
       "      <td>20.788390</td>\n",
       "      <td>19.558775</td>\n",
       "      <td>22.208947</td>\n",
       "      <td>23.424717</td>\n",
       "      <td>22.807790</td>\n",
       "      <td>22.861086</td>\n",
       "      <td>23.008517</td>\n",
       "      <td>23.536248</td>\n",
       "      <td>23.327999</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-02-20</th>\n",
       "      <td>20.838095</td>\n",
       "      <td>22.504042</td>\n",
       "      <td>25.609772</td>\n",
       "      <td>27.64638</td>\n",
       "      <td>25.06115</td>\n",
       "      <td>23.619240</td>\n",
       "      <td>20.788390</td>\n",
       "      <td>19.558775</td>\n",
       "      <td>22.208947</td>\n",
       "      <td>23.424717</td>\n",
       "      <td>22.807790</td>\n",
       "      <td>22.861086</td>\n",
       "      <td>23.408320</td>\n",
       "      <td>23.287588</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3     lag_4     lag_5      lag_6  \\\n",
       "2012-02-18  25.609772  27.646380  25.061150  23.61924  20.78839  19.558775   \n",
       "2012-02-19  22.504042  25.609772  27.646380  25.06115  23.61924  20.788390   \n",
       "2012-02-20  20.838095  22.504042  25.609772  27.64638  25.06115  23.619240   \n",
       "\n",
       "                lag_7      lag_8      lag_9     lag_10     lag_11     lag_12  \\\n",
       "2012-02-18  22.208947  23.424717  22.807790  22.861086  23.008517  21.763739   \n",
       "2012-02-19  19.558775  22.208947  23.424717  22.807790  22.861086  23.008517   \n",
       "2012-02-20  20.788390  19.558775  22.208947  23.424717  22.807790  22.861086   \n",
       "\n",
       "            roll_mean_24  roll_mean_48  _level_skforecast  month  \n",
       "2012-02-18     23.796391     23.031106                  0      2  \n",
       "2012-02-19     23.536248     23.327999                  0      2  \n",
       "2012-02-20     23.408320     23.287588                  0      2  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# X_train slice for item_1\n",
    "# ==============================================================================\n",
    "X_train.loc[X_train['_level_skforecast'] == 0].head(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "62aa0f6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>lag_4</th>\n",
       "      <th>lag_5</th>\n",
       "      <th>lag_6</th>\n",
       "      <th>lag_7</th>\n",
       "      <th>lag_8</th>\n",
       "      <th>lag_9</th>\n",
       "      <th>lag_10</th>\n",
       "      <th>lag_11</th>\n",
       "      <th>lag_12</th>\n",
       "      <th>roll_mean_24</th>\n",
       "      <th>roll_mean_48</th>\n",
       "      <th>_level_skforecast</th>\n",
       "      <th>month</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-02-18</th>\n",
       "      <td>20.221875</td>\n",
       "      <td>28.195833</td>\n",
       "      <td>22.970833</td>\n",
       "      <td>19.903125</td>\n",
       "      <td>19.239583</td>\n",
       "      <td>18.446875</td>\n",
       "      <td>19.858333</td>\n",
       "      <td>20.844792</td>\n",
       "      <td>17.282292</td>\n",
       "      <td>17.295833</td>\n",
       "      <td>18.459375</td>\n",
       "      <td>18.979167</td>\n",
       "      <td>21.431597</td>\n",
       "      <td>21.400473</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-02-19</th>\n",
       "      <td>19.176042</td>\n",
       "      <td>20.221875</td>\n",
       "      <td>28.195833</td>\n",
       "      <td>22.970833</td>\n",
       "      <td>19.903125</td>\n",
       "      <td>19.239583</td>\n",
       "      <td>18.446875</td>\n",
       "      <td>19.858333</td>\n",
       "      <td>20.844792</td>\n",
       "      <td>17.282292</td>\n",
       "      <td>17.295833</td>\n",
       "      <td>18.459375</td>\n",
       "      <td>21.121788</td>\n",
       "      <td>21.361480</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-02-20</th>\n",
       "      <td>21.991667</td>\n",
       "      <td>19.176042</td>\n",
       "      <td>20.221875</td>\n",
       "      <td>28.195833</td>\n",
       "      <td>22.970833</td>\n",
       "      <td>19.903125</td>\n",
       "      <td>19.239583</td>\n",
       "      <td>18.446875</td>\n",
       "      <td>19.858333</td>\n",
       "      <td>20.844792</td>\n",
       "      <td>17.282292</td>\n",
       "      <td>17.295833</td>\n",
       "      <td>21.214800</td>\n",
       "      <td>21.265929</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3      lag_4      lag_5      lag_6  \\\n",
       "2012-02-18  20.221875  28.195833  22.970833  19.903125  19.239583  18.446875   \n",
       "2012-02-19  19.176042  20.221875  28.195833  22.970833  19.903125  19.239583   \n",
       "2012-02-20  21.991667  19.176042  20.221875  28.195833  22.970833  19.903125   \n",
       "\n",
       "                lag_7      lag_8      lag_9     lag_10     lag_11     lag_12  \\\n",
       "2012-02-18  19.858333  20.844792  17.282292  17.295833  18.459375  18.979167   \n",
       "2012-02-19  18.446875  19.858333  20.844792  17.282292  17.295833  18.459375   \n",
       "2012-02-20  19.239583  18.446875  19.858333  20.844792  17.282292  17.295833   \n",
       "\n",
       "            roll_mean_24  roll_mean_48  _level_skforecast  month  \n",
       "2012-02-18     21.431597     21.400473                  1      2  \n",
       "2012-02-19     21.121788     21.361480                  1      2  \n",
       "2012-02-20     21.214800     21.265929                  1      2  "
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# X_train slice for item_2\n",
    "# ==============================================================================\n",
    "X_train.loc[X_train['_level_skforecast'] == 1].head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b01c641",
   "metadata": {},
   "source": [
    "To use exogenous variables in backtesting or hyperparameter tuning, they must be specified with the `exog` argument."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "bcbb06a9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "77e7de7b12ba41cdb20efe0a62b95a46",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/8 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>levels</th>\n",
       "      <th>mean_absolute_error</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>item_1</td>\n",
       "      <td>1.277778</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>item_2</td>\n",
       "      <td>2.497446</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>item_3</td>\n",
       "      <td>3.137108</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>average</td>\n",
       "      <td>2.304111</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>weighted_average</td>\n",
       "      <td>2.304111</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>pooling</td>\n",
       "      <td>2.304111</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             levels  mean_absolute_error\n",
       "0            item_1             1.277778\n",
       "1            item_2             2.497446\n",
       "2            item_3             3.137108\n",
       "3           average             2.304111\n",
       "4  weighted_average             2.304111\n",
       "5           pooling             2.304111"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>fold</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>0</td>\n",
       "      <td>25.609387</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>0</td>\n",
       "      <td>10.674722</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_3</td>\n",
       "      <td>0</td>\n",
       "      <td>11.716675</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_1</td>\n",
       "      <td>0</td>\n",
       "      <td>25.267054</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level  fold       pred\n",
       "2014-07-16  item_1     0  25.609387\n",
       "2014-07-16  item_2     0  10.674722\n",
       "2014-07-16  item_3     0  11.716675\n",
       "2014-07-17  item_1     0  25.267054"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Backtesting Multi-Series with exog\n",
    "# ==============================================================================\n",
    "cv = TimeSeriesFold(\n",
    "         steps              = 24,\n",
    "         initial_train_size = '2014-07-15 23:59:00',\n",
    "         refit              = True,\n",
    "     )\n",
    "\n",
    "metrics_levels, backtest_predictions = backtesting_forecaster_multiseries(\n",
    "    forecaster            = forecaster,\n",
    "    series                = series_long,\n",
    "    exog                  = exog_wide,\n",
    "    cv                    = cv,\n",
    "    levels                = None,\n",
    "    metric                = 'mean_absolute_error',\n",
    "    add_aggregated_metric = True,\n",
    "    suppress_warnings     = True\n",
    ")\n",
    "\n",
    "display(metrics_levels)\n",
    "backtest_predictions.head(4)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "da302dd6",
   "metadata": {},
   "source": [
    "## Series transformations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba8c8ed6",
   "metadata": {},
   "source": [
    "<code>ForecasterRecursiveMultiSeries</code> allows to transform series before training the model using the argument `transformer_series`, three diferent options are available:\n",
    "\n",
    "+ `transformer_series` is a single transformer: When a single transformer is provided, it is automatically cloned for each individual series. Each cloned transformer is then trained separately on one of the series.\n",
    "\n",
    "+ `transformer_series` is a dictionary: A different transformer can be specified for each series by passing a dictionary where the keys correspond to the series names and the values are the transformers. Each series is transformed according to its designated transformer. When this option is used, it is mandatory to include a transformer for unknown series, which is indicated by the key `'_unknown_level'`.\n",
    "\n",
    "+ `transformer_series` is `None`: no transformations are applied to any of the series.\n",
    "\n",
    "Regardless of the configuration, each series is transformed independently. Even when using a single transformer, it is cloned internally and applied separately to each series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "0d13c7ad",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <style>\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 {\n",
       "            font-family: 'Arial', sans-serif;\n",
       "            font-size: 0.9em;\n",
       "            color: #333333;\n",
       "            border: 1px solid #ddd;\n",
       "            background-color: #f0f8ff;\n",
       "            padding: 5px 15px;\n",
       "            border-radius: 8px;\n",
       "            max-width: 600px;\n",
       "            #margin: auto;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 h2 {\n",
       "            font-size: 1.5em;\n",
       "            color: #222222;\n",
       "            border-bottom: 2px solid #ddd;\n",
       "            padding-bottom: 5px;\n",
       "            margin-bottom: 15px;\n",
       "            margin-top: 5px;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 details {\n",
       "            margin: 10px 0;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 summary {\n",
       "            font-weight: bold;\n",
       "            font-size: 1.1em;\n",
       "            color: #000000;\n",
       "            cursor: pointer;\n",
       "            margin-bottom: 5px;\n",
       "            background-color: #b3dbfd;\n",
       "            padding: 5px;\n",
       "            border-radius: 5px;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 summary:hover {\n",
       "            color: #000000;\n",
       "            background-color: #e0e0e0;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 ul {\n",
       "            font-family: 'Courier New', monospace;\n",
       "            list-style-type: none;\n",
       "            padding-left: 20px;\n",
       "            margin: 10px 0;\n",
       "            line-height: normal;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 li {\n",
       "            margin: 5px 0;\n",
       "            font-family: 'Courier New', monospace;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 li strong {\n",
       "            font-weight: bold;\n",
       "            color: #444444;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 li::before {\n",
       "            content: \"- \";\n",
       "            color: #666666;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 a {\n",
       "            color: #001633;\n",
       "            text-decoration: none;\n",
       "        }\n",
       "        .container-a6865a3e3ad744bf82eef4dfe4eed1c6 a:hover {\n",
       "            color: #359ccb; \n",
       "        }\n",
       "    </style>\n",
       "    \n",
       "        <div class=\"container-a6865a3e3ad744bf82eef4dfe4eed1c6\">\n",
       "            <p style=\"font-size: 1.5em; font-weight: bold; margin-block-start: 0.83em; margin-block-end: 0.83em;\">ForecasterRecursiveMultiSeries</p>\n",
       "            <details open>\n",
       "                <summary>General Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Estimator:</strong> LGBMRegressor</li>\n",
       "                    <li><strong>Lags:</strong> [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]</li>\n",
       "                    <li><strong>Window features:</strong> ['roll_mean_24', 'roll_mean_48']</li>\n",
       "                    <li><strong>Window size:</strong> 48</li>\n",
       "                    <li><strong>Series encoding:</strong> ordinal</li>\n",
       "                    <li><strong>Exogenous included:</strong> False</li>\n",
       "                    <li><strong>Weight function included:</strong> False</li>\n",
       "                    <li><strong>Series weights:</strong> None</li>\n",
       "                    <li><strong>Differentiation order:</strong> None</li>\n",
       "                    <li><strong>Creation date:</strong> 2025-11-26 15:16:55</li>\n",
       "                    <li><strong>Last fit date:</strong> 2025-11-26 15:16:56</li>\n",
       "                    <li><strong>Skforecast version:</strong> 0.19.0</li>\n",
       "                    <li><strong>Python version:</strong> 3.12.11</li>\n",
       "                    <li><strong>Forecaster id:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Exogenous Variables</summary>\n",
       "                <ul>\n",
       "                    None\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Data Transformations</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Transformer for series:</strong> StandardScaler()</li>\n",
       "                    <li><strong>Transformer for exog:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Training Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Series names (levels):</strong> item_1, item_2, item_3</li>\n",
       "                    <li><strong>Training range:</strong> 'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'], 'item_3': ['2012-01-01', '2014-07-15']</li>\n",
       "                    <li><strong>Training index type:</strong> DatetimeIndex</li>\n",
       "                    <li><strong>Training index frequency:</strong> <Day></li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Estimator Parameters</summary>\n",
       "                <ul>\n",
       "                    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Fit Kwargs</summary>\n",
       "                <ul>\n",
       "                    {}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <p>\n",
       "                <a href=\"https://skforecast.org/0.19.0/api/forecasterrecursivemultiseries.html\">&#128712 <strong>API Reference</strong></a>\n",
       "                &nbsp;&nbsp;\n",
       "                <a href=\"https://skforecast.org/0.19.0/user_guides/independent-multi-time-series-forecasting.html\">&#128462 <strong>User Guide</strong></a>\n",
       "            </p>\n",
       "        </div>\n",
       "        "
      ],
      "text/plain": [
       "============================== \n",
       "ForecasterRecursiveMultiSeries \n",
       "============================== \n",
       "Estimator: LGBMRegressor \n",
       "Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] \n",
       "Window features: ['roll_mean_24', 'roll_mean_48'] \n",
       "Window size: 48 \n",
       "Series encoding: ordinal \n",
       "Series names (levels): item_1, item_2, item_3 \n",
       "Exogenous included: False \n",
       "Exogenous names: None \n",
       "Transformer for series: StandardScaler() \n",
       "Transformer for exog: None \n",
       "Weight function included: False \n",
       "Series weights: None \n",
       "Differentiation order: None \n",
       "Training range: \n",
       "    'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'],\n",
       "    'item_3': ['2012-01-01', '2014-07-15'] \n",
       "Training index type: DatetimeIndex \n",
       "Training index frequency: <Day> \n",
       "Estimator parameters: \n",
       "    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0,\n",
       "    'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1,\n",
       "    'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0,\n",
       "    'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None,\n",
       "    'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0,\n",
       "    'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1} \n",
       "fit_kwargs: {} \n",
       "Creation date: 2025-11-26 15:16:55 \n",
       "Last fit date: 2025-11-26 15:16:56 \n",
       "Skforecast version: 0.19.0 \n",
       "Python version: 3.12.11 \n",
       "Forecaster id: None "
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Series transformation: same transformation for all series\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator          = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags               = 24,\n",
    "                 window_features    = RollingFeatures(stats=['mean', 'mean'], window_sizes=[24, 48]),\n",
    "                 encoding           = 'ordinal',\n",
    "                 transformer_series = StandardScaler(),\n",
    "                 transformer_exog   = None\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train, suppress_warnings=True)\n",
    "forecaster"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44e58643",
   "metadata": {},
   "source": [
    "It is possible to access the fitted transformers for each series through the `transformers_series_` attribute. This allows verification that each transformer has been trained independently."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "220f534e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Series item_1: StandardScaler() mean=[22.47606719], scale=[2.56240321]\n",
      "Series item_2: StandardScaler() mean=[16.41739687], scale=[5.00145466]\n",
      "Series item_3: StandardScaler() mean=[17.30064109], scale=[5.53439225]\n",
      "Series _unknown_level: StandardScaler() mean=[18.73136838], scale=[5.2799675]\n"
     ]
    }
   ],
   "source": [
    "# Mean and scale of the transformer for each series\n",
    "# ==============================================================================\n",
    "for k, v in forecaster.transformer_series_.items():\n",
    "    print(f\"Series {k}: {v} mean={v.mean_}, scale={v.scale_}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "9c6cce05",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭────────────────────────────────── InputTypeWarning ──────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Passing a DataFrame (either wide or long format) as `series` requires additional     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> internal transformations, which can increase computational time. It is recommended   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> to use a dictionary of pandas Series instead. For more details, see:                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> html#input-data                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.InputTypeWarning                                    <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:2349                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m InputTypeWarning \u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Passing a DataFrame (either wide or long format) as `series` requires additional     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m internal transformations, which can increase computational time. It is recommended   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m to use a dictionary of pandas Series instead. For more details, see:                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m html#input-data                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.InputTypeWarning                                    \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:2349                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭─────────────────────────────── IgnoredArgumentWarning ───────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> {'item_3'} not present in `transformer_series`. No transformation is applied to      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> these series.                                                                        <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.IgnoredArgumentWarning                              <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:371                                                                          <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=IgnoredArgumentWarning)          <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m──────────────────────────────\u001b[0m\u001b[38;5;214m IgnoredArgumentWarning \u001b[0m\u001b[38;5;214m──────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m {'item_3'} not present in `transformer_series`. No transformation is applied to      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m these series.                                                                        \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.IgnoredArgumentWarning                              \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:371                                                                          \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=IgnoredArgumentWarning)          \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Series transformation: different transformation for each series\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator          = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags               = 24,\n",
    "                 window_features    = RollingFeatures(stats=['mean', 'mean'], window_sizes=[24, 48]),\n",
    "                 encoding           = 'ordinal',\n",
    "                 transformer_series = {'item_1': StandardScaler(), 'item_2': MinMaxScaler(), '_unknown_level': StandardScaler()},\n",
    "                 transformer_exog   = None\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "e91dc7ed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Series item_1: {'copy': True, 'with_mean': True, 'with_std': True}\n",
      "Series item_2: {'clip': False, 'copy': True, 'feature_range': (0, 1)}\n",
      "Series item_3: None\n",
      "Series _unknown_level: {'copy': True, 'with_mean': True, 'with_std': True}\n"
     ]
    }
   ],
   "source": [
    "# Transformer trained for each series\n",
    "# ==============================================================================\n",
    "for k, v in forecaster.transformer_series_.items():\n",
    "    if v is not None:\n",
    "        print(f\"Series {k}: {v.get_params()}\")\n",
    "    else:\n",
    "        print(f\"Series {k}: {v}\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "0d93ddc5",
   "metadata": {},
   "source": [
    "## Hyperparameter search and lags selection\n",
    "\n",
    "Hyperparameter tuning consists of systematically evaluating combinations of hyperparameters (including lags) to find the configuration that yields the best predictive performance. The **skforecast** library supports several tuning strategies: **grid search**, **random search**, and **Bayesian search**. These strategies can be used with either [backtesting](../user_guides/backtesting.html) or [one-step-ahead validation](../user_guides/hyperparameter-tuning-and-lags-selection.html#one-step-ahead-validation) to determine the optimal parameter set for a given forecasting task.\n",
    "\n",
    "The functions `grid_search_forecaster_multiseries`, `random_search_forecaster_multiseries` and `bayesian_search_forecaster_multiseries` from the `model_selection` module allow for **lags and hyperparameter optimization**.\n",
    "\n",
    "The `levels` argument is crucial in these functions, as it specifies **which time series are considered** during the optimization:\n",
    "\n",
    "+ If `levels` is a `list`, the function searches for the configuration that minimizes the aggregated error across the selected series.\n",
    "\n",
    "+ If `levels = None`, all available series are used in the optimization.\n",
    "\n",
    "+ If `levels = 'item_1'` (equivalent to `levels = ['item_1']`), the optimization is based solely on the error of that specific series, and the returned metric corresponds to it.\n",
    "\n",
    "When optimizing across multiple series, the resulting metrics must be **aggregated**. The available methods are:\n",
    "\n",
    "+ `'average'`, the average (arithmetic mean) of all series (`levels`).\n",
    "\n",
    "+ `'weighted_average'`, the average of the metrics weighted by the number of predicted values of each series (`levels`).\n",
    "\n",
    "+ `'pooling'`, the values of all series (`levels`) are pooled and then the metric is calculated.\n",
    "\n",
    "If a `list` of aggregation methods is provided to the `aggregate_metric` argument, all are computed, but only the **first method** is used to select the **best configuration**.\n",
    "\n",
    "The following example demonstrates how to use `grid_search_forecaster_multiseries` to find the best lags and hyperparameters for all series (all `levels`) using `'weighted_average'` as the aggregation strategy."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9535c8d",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,191,191,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00bfa5; border-color: #00bfa5; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00bfa5;\"></i>\n",
    "    <b style=\"color: #00bfa5;\">&#128161 Tip</b>\n",
    "</p>\n",
    "\n",
    "More information about <b>time series forecasting metrics</b> can be found in the <a href=\"../user_guides/metrics.html\">Metrics</a> guide.\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "adfd939a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create Forecaster Multi-Series\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 24,\n",
    "                 encoding  = 'ordinal'\n",
    "             )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "f27629c0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "74587d6c9d84494aabc6c8be04a711e3",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "lags grid:   0%|          | 0/2 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "69871d6a812e4bf9940b81a38f9dbb71",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "params grid:   0%|          | 0/4 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "`Forecaster` refitted using the best-found lags and parameters, and the whole data set: \n",
      "  Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24\n",
      " 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48] \n",
      "  Parameters: {'max_depth': 7, 'n_estimators': 20}\n",
      "  Backtesting metric: 2.302108637662591\n",
      "  Levels: ['item_1', 'item_2', 'item_3']\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>levels</th>\n",
       "      <th>lags</th>\n",
       "      <th>lags_label</th>\n",
       "      <th>params</th>\n",
       "      <th>mean_absolute_error__weighted_average</th>\n",
       "      <th>max_depth</th>\n",
       "      <th>n_estimators</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>48 lags</td>\n",
       "      <td>{'max_depth': 7, 'n_estimators': 20}</td>\n",
       "      <td>2.302109</td>\n",
       "      <td>7</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>24 lags</td>\n",
       "      <td>{'max_depth': 7, 'n_estimators': 20}</td>\n",
       "      <td>2.363481</td>\n",
       "      <td>7</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>48 lags</td>\n",
       "      <td>{'max_depth': 3, 'n_estimators': 20}</td>\n",
       "      <td>2.439888</td>\n",
       "      <td>3</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>24 lags</td>\n",
       "      <td>{'max_depth': 3, 'n_estimators': 20}</td>\n",
       "      <td>2.486789</td>\n",
       "      <td>3</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                     levels  \\\n",
       "0  [item_1, item_2, item_3]   \n",
       "1  [item_1, item_2, item_3]   \n",
       "2  [item_1, item_2, item_3]   \n",
       "3  [item_1, item_2, item_3]   \n",
       "\n",
       "                                                lags lags_label  \\\n",
       "0  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...    48 lags   \n",
       "1  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...    24 lags   \n",
       "2  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...    48 lags   \n",
       "3  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...    24 lags   \n",
       "\n",
       "                                 params  \\\n",
       "0  {'max_depth': 7, 'n_estimators': 20}   \n",
       "1  {'max_depth': 7, 'n_estimators': 20}   \n",
       "2  {'max_depth': 3, 'n_estimators': 20}   \n",
       "3  {'max_depth': 3, 'n_estimators': 20}   \n",
       "\n",
       "   mean_absolute_error__weighted_average  max_depth  n_estimators  \n",
       "0                               2.302109          7            20  \n",
       "1                               2.363481          7            20  \n",
       "2                               2.439888          3            20  \n",
       "3                               2.486789          3            20  "
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Grid search Multi-Series\n",
    "# ==============================================================================\n",
    "lags_grid = {\n",
    "    '24 lags': 24,\n",
    "    '48 lags': 48\n",
    "}\n",
    "\n",
    "param_grid = {\n",
    "    'n_estimators': [10, 20],\n",
    "    'max_depth': [3, 7]\n",
    "}\n",
    "\n",
    "levels = ['item_1', 'item_2', 'item_3']\n",
    "\n",
    "cv = TimeSeriesFold(\n",
    "         steps              = 24,\n",
    "         initial_train_size = '2014-07-15 23:59:00',  # end_train\n",
    "         refit              = False\n",
    "     )\n",
    "\n",
    "results = grid_search_forecaster_multiseries(\n",
    "              forecaster        = forecaster,\n",
    "              series            = series_long,\n",
    "              exog              = exog_wide,\n",
    "              lags_grid         = lags_grid,\n",
    "              param_grid        = param_grid,\n",
    "              cv                = cv,\n",
    "              levels            = levels,\n",
    "              metric            = 'mean_absolute_error',\n",
    "              aggregate_metric  = 'weighted_average',\n",
    "              suppress_warnings = True\n",
    "          )\n",
    "\n",
    "results.head(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89dbbf3b",
   "metadata": {},
   "source": [
    "It is also possible to perform a bayesian optimization with **Optuna** using the `bayesian_search_forecaster_multiseries` function. For more information about this type of optimization, visit the [user guide](../user_guides/hyperparameter-tuning-and-lags-selection.html#bayesian-search)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "b4505b02",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "50788301bc87479f80efc61703a163c5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "  0%|          | 0/5 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "`Forecaster` refitted using the best-found lags and parameters, and the whole data set: \n",
      "  Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24\n",
      " 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48] \n",
      "  Parameters: {'n_estimators': 16, 'min_samples_leaf': 9, 'max_features': 'log2'}\n",
      "  Backtesting metric: 2.1762208064165525\n",
      "  Levels: ['item_1', 'item_2', 'item_3']\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>levels</th>\n",
       "      <th>lags</th>\n",
       "      <th>params</th>\n",
       "      <th>mean_absolute_error__weighted_average</th>\n",
       "      <th>mean_absolute_error__average</th>\n",
       "      <th>mean_absolute_error__pooling</th>\n",
       "      <th>n_estimators</th>\n",
       "      <th>min_samples_leaf</th>\n",
       "      <th>max_features</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'n_estimators': 16, 'min_samples_leaf': 9, 'm...</td>\n",
       "      <td>2.176221</td>\n",
       "      <td>2.176221</td>\n",
       "      <td>2.176221</td>\n",
       "      <td>16</td>\n",
       "      <td>9</td>\n",
       "      <td>log2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'n_estimators': 15, 'min_samples_leaf': 4, 'm...</td>\n",
       "      <td>2.212821</td>\n",
       "      <td>2.212821</td>\n",
       "      <td>2.212821</td>\n",
       "      <td>15</td>\n",
       "      <td>4</td>\n",
       "      <td>sqrt</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'n_estimators': 14, 'min_samples_leaf': 8, 'm...</td>\n",
       "      <td>2.238313</td>\n",
       "      <td>2.238313</td>\n",
       "      <td>2.238313</td>\n",
       "      <td>14</td>\n",
       "      <td>8</td>\n",
       "      <td>log2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'n_estimators': 13, 'min_samples_leaf': 3, 'm...</td>\n",
       "      <td>2.263358</td>\n",
       "      <td>2.263358</td>\n",
       "      <td>2.263358</td>\n",
       "      <td>13</td>\n",
       "      <td>3</td>\n",
       "      <td>sqrt</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                     levels  \\\n",
       "0  [item_1, item_2, item_3]   \n",
       "1  [item_1, item_2, item_3]   \n",
       "2  [item_1, item_2, item_3]   \n",
       "3  [item_1, item_2, item_3]   \n",
       "\n",
       "                                                lags  \\\n",
       "0  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "1  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "2  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "3  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "\n",
       "                                              params  \\\n",
       "0  {'n_estimators': 16, 'min_samples_leaf': 9, 'm...   \n",
       "1  {'n_estimators': 15, 'min_samples_leaf': 4, 'm...   \n",
       "2  {'n_estimators': 14, 'min_samples_leaf': 8, 'm...   \n",
       "3  {'n_estimators': 13, 'min_samples_leaf': 3, 'm...   \n",
       "\n",
       "   mean_absolute_error__weighted_average  mean_absolute_error__average  \\\n",
       "0                               2.176221                      2.176221   \n",
       "1                               2.212821                      2.212821   \n",
       "2                               2.238313                      2.238313   \n",
       "3                               2.263358                      2.263358   \n",
       "\n",
       "   mean_absolute_error__pooling  n_estimators  min_samples_leaf max_features  \n",
       "0                      2.176221            16                 9         log2  \n",
       "1                      2.212821            15                 4         sqrt  \n",
       "2                      2.238313            14                 8         log2  \n",
       "3                      2.263358            13                 3         sqrt  "
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Bayesian search hyperparameters and lags with Optuna\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 24,\n",
    "                 encoding  = 'ordinal'\n",
    "             )\n",
    "\n",
    "levels = ['item_1', 'item_2', 'item_3']\n",
    "\n",
    "# Search space\n",
    "def search_space(trial):\n",
    "    search_space  = {\n",
    "        'lags'            : trial.suggest_categorical('lags', [24, 48]),\n",
    "        'n_estimators'    : trial.suggest_int('n_estimators', 10, 20),\n",
    "        'min_samples_leaf': trial.suggest_int('min_samples_leaf', 1, 10),\n",
    "        'max_features'    : trial.suggest_categorical('max_features', ['log2', 'sqrt'])\n",
    "    }\n",
    "\n",
    "    return search_space\n",
    "\n",
    "cv = OneStepAheadFold(initial_train_size = '2014-07-15 23:59:00')\n",
    "\n",
    "results, best_trial = bayesian_search_forecaster_multiseries(\n",
    "    forecaster        = forecaster,\n",
    "    series            = series_long,\n",
    "    exog              = exog_wide,\n",
    "    search_space      = search_space,\n",
    "    cv                = cv,\n",
    "    levels            = levels,\n",
    "    metric            = 'mean_absolute_error',\n",
    "    aggregate_metric  = ['weighted_average', 'average', 'pooling'],\n",
    "    n_trials          = 5,\n",
    "    suppress_warnings = True\n",
    ")\n",
    "\n",
    "results.head(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "114fb605",
   "metadata": {},
   "source": [
    "The `best_trial` return contains the details of the trial that achieved the best result during optimization. For more information, refer to the [Study class](https://optuna.readthedocs.io/en/stable/reference/generated/optuna.study.Study.html#optuna.study.Study)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "24e4c7b2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "FrozenTrial(number=3, state=1, values=[2.1762208064165525], datetime_start=datetime.datetime(2025, 11, 26, 15, 16, 58, 66792), datetime_complete=datetime.datetime(2025, 11, 26, 15, 16, 58, 126478), params={'lags': 48, 'n_estimators': 16, 'min_samples_leaf': 9, 'max_features': 'log2'}, user_attrs={}, system_attrs={}, intermediate_values={}, distributions={'lags': CategoricalDistribution(choices=(24, 48)), 'n_estimators': IntDistribution(high=20, log=False, low=10, step=1), 'min_samples_leaf': IntDistribution(high=10, log=False, low=1, step=1), 'max_features': CategoricalDistribution(choices=('log2', 'sqrt'))}, trial_id=3, value=None)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Optuna best trial in the study\n",
    "# ==============================================================================\n",
    "best_trial"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "d6130828",
   "metadata": {},
   "source": [
    "## Series with different lengths and different exogenous variables"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96d201a3",
   "metadata": {},
   "source": [
    "The `ForecasterRecursiveMultiSeries` class supports simultaneous modeling of multiple time series, even when they differ in length and use distinct exogenous variables. Various input formats are supported, provided the following conditions are met:\n",
    "\n",
    "+ **When all series have the same length and share the same exogenous variables**:\n",
    "  - Use a **wide-format DataFrame**, where each column represents a different time series or exogenous variable. This is the simplest format.\n",
    "\n",
    "+ **When series have different lengths**, two formats are supported:\n",
    "  \n",
    "  - A **long-format DataFrame with a MultiIndex**: The first index level must contain the series IDs, and the second must be a `pandas.DatetimeIndex` with the same frequency across all series.\n",
    "  \n",
    "  - A **dictionary**: Each key is a series ID and each value is a named `pandas.Series`. All series must have either a `pandas.DatetimeIndex` or `RangeIndex` with consistent frequency or step size.\n",
    "\n",
    "+ **When exogenous variables differ between series**, two formats are supported:\n",
    "  \n",
    "  - A **long-format DataFrame with a MultiIndex**: The first index level must contain the series IDs, and the second must be a `pandas.DatetimeIndex`. Each column represents a different exogenous variable. No frequency or step size is required.\n",
    "  \n",
    "  - A **dictionary**: Each key is a series ID and each value is a named `pandas.Series` or `DataFrame` containing the exogenous variables.  No frequency or step size is required.\n",
    "\n",
    "\n",
    "> Note: Frequency or step size is required **only** for the series index. Exogenous variables do **not** require a specific frequency or step size, as they may not span the entire time period of the series.\n",
    "\n",
    "<br>\n",
    "\n",
    "| Series Type            | Exog Type                                         | Index Requirements                      |\n",
    "|:----------------------:|:-------------------------------------------------:|:----------------------------------------|\n",
    "| `Wide DataFrame`       | `Wide DataFrame`, `MultiIndex DataFrame`, `dict` | `pandas.DatetimeIndex` or `RangeIndex`  |\n",
    "| `MultiIndex DataFrame` | `Wide DataFrame`, `MultiIndex DataFrame`, `dict` | `pandas.DatetimeIndex`                  |\n",
    "| `dict`                 | `Wide DataFrame`, `MultiIndex DataFrame`, `dict` | `pandas.DatetimeIndex` or `RangeIndex`  |\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "afb2c111",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>lag_4</th>\n",
       "      <th>_level_skforecast</th>\n",
       "      <th>month</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-05</th>\n",
       "      <td>1.334476</td>\n",
       "      <td>1.979794</td>\n",
       "      <td>0.117764</td>\n",
       "      <td>-5.550607</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-06</th>\n",
       "      <td>-0.428047</td>\n",
       "      <td>1.334476</td>\n",
       "      <td>1.979794</td>\n",
       "      <td>0.117764</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-07</th>\n",
       "      <td>-0.534430</td>\n",
       "      <td>-0.428047</td>\n",
       "      <td>1.334476</td>\n",
       "      <td>1.979794</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "               lag_1     lag_2     lag_3     lag_4  _level_skforecast  month\n",
       "2012-01-05  1.334476  1.979794  0.117764 -5.550607                  0      1\n",
       "2012-01-06 -0.428047  1.334476  1.979794  0.117764                  0      1\n",
       "2012-01-07 -0.534430 -0.428047  1.334476  1.979794                  0      1"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Series and exog as DataFrames \n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator          = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags               = 4,\n",
    "                 encoding           = 'ordinal',\n",
    "                 transformer_series = StandardScaler()\n",
    "             )\n",
    "\n",
    "X_train, y_train = forecaster.create_train_X_y(\n",
    "                       series            = series_long_train,\n",
    "                       exog              = exog_wide_train,\n",
    "                       suppress_warnings = True\n",
    "                   )\n",
    "X_train.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "666d8251",
   "metadata": {},
   "source": [
    "When `exog` is a dictionary of `pandas Series` or `DataFrames`, different exogenous variables can be used for each series or the same exogenous variable can have different values for each series."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "b5d912fb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Ilustrative example of different values for the same exogenous variable\n",
    "# ==============================================================================\n",
    "n_rows_train = len(exog_wide_train)\n",
    "n_rows_test = len(exog_wide_test)\n",
    "\n",
    "exog_1_item_1_train = pd.Series([1] * n_rows_train, name='exog_1', index=exog_wide_train.index)\n",
    "exog_1_item_2_train = pd.Series([10] * n_rows_train, name='exog_1', index=exog_wide_train.index)\n",
    "exog_1_item_3_train = pd.Series([100] * n_rows_train, name='exog_1', index=exog_wide_train.index)\n",
    "\n",
    "exog_1_item_1_test = pd.Series([1] * n_rows_test, name='exog_1', index=exog_wide_test.index)\n",
    "exog_1_item_2_test = pd.Series([10] * n_rows_test, name='exog_1', index=exog_wide_test.index)\n",
    "exog_1_item_3_test = pd.Series([100] * n_rows_test, name='exog_1', index=exog_wide_test.index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "b9090a1b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>lag_4</th>\n",
       "      <th>_level_skforecast</th>\n",
       "      <th>exog_1</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-05</th>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>8.253175</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-06</th>\n",
       "      <td>21.379238</td>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-07</th>\n",
       "      <td>21.106643</td>\n",
       "      <td>21.379238</td>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3      lag_4  _level_skforecast  \\\n",
       "2012-01-05  25.895533  27.549099  22.777826   8.253175                  0   \n",
       "2012-01-06  21.379238  25.895533  27.549099  22.777826                  0   \n",
       "2012-01-07  21.106643  21.379238  25.895533  27.549099                  0   \n",
       "\n",
       "            exog_1  \n",
       "2012-01-05       1  \n",
       "2012-01-06       1  \n",
       "2012-01-07       1  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Column `exog_1` as different values for each item ('_level_skforecast' id):\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "exog_1\n",
       "1      923\n",
       "10     923\n",
       "100    923\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Series as DataFrame and exog as dict\n",
    "# ==============================================================================\n",
    "exog_dict_train = {\n",
    "    'item_1': exog_1_item_1_train,\n",
    "    'item_2': exog_1_item_2_train,\n",
    "    'item_3': exog_1_item_3_train\n",
    "}\n",
    "\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 4,\n",
    "                 encoding  = 'ordinal'\n",
    "             )\n",
    "\n",
    "X_train, y_train = forecaster.create_train_X_y(\n",
    "                       series            = series_long_train,\n",
    "                       exog              = exog_dict_train,\n",
    "                       suppress_warnings = True\n",
    "                   )\n",
    "\n",
    "display(X_train.head(3))\n",
    "print(\"\")\n",
    "print(\"Column `exog_1` as different values for each item ('_level_skforecast' id):\")\n",
    "X_train['exog_1'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "20991082",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.648910</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>10.677388</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_3</td>\n",
       "      <td>12.402632</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_1  25.648910\n",
       "2014-07-16  item_2  10.677388\n",
       "2014-07-16  item_3  12.402632"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Predict with series as DataFrame and exog as dict\n",
    "# ==============================================================================\n",
    "forecaster.fit(\n",
    "    series            = series_long_train,\n",
    "    exog              = exog_dict_train,\n",
    "    suppress_warnings = True\n",
    ")\n",
    "\n",
    "exog_dict_pred = {\n",
    "    'item_1': exog_1_item_1_test,\n",
    "    'item_2': exog_1_item_2_test,\n",
    "    'item_3': exog_1_item_3_test\n",
    "}\n",
    "\n",
    "predictions = forecaster.predict(steps=24, exog=exog_dict_pred)\n",
    "predictions.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25362369",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,191,191,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00bfa5; border-color: #00bfa5; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00bfa5;\"></i>\n",
    "    <b style=\"color: #00bfa5;\">&#128161 Tip</b>\n",
    "</p>\n",
    "\n",
    "<p>\n",
    "When working with time series of different lengths and distinct exogenous variables, it is recommended to use both <code>series</code> and <code>exog</code> as dictionaries. This approach simplifies data management and reduces the likelihood of errors.\n",
    "\n",
    "For a detailed example, see the user guide <a href=\"../user_guides/multi-series-with-different-length-and-different_exog.html\">Global Forecasting Models: Time series with different lengths and different exogenous variables</a>.\n",
    "\n",
    "For a broader overview of how to incorporate exogenous variables in forecasting models, refer to the <a href=\"../user_guides/exogenous-variables.html\">Exogenous Variables User Guide</a>.\n",
    "</p>\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8cb6d36b",
   "metadata": {},
   "source": [
    "## Series Encoding in multi-series\n",
    "\n",
    "When creating the training matrices, the <code>ForecasterRecursiveMultiSeries</code> class encodes the series names to identify the series to which the observations belong. Different encoding methods can be used:\n",
    "\n",
    "- `'ordinal'` (default), a single column (`_level_skforecast`) is created with integer values from 0 to n_series - 1.\n",
    "\n",
    "- `'ordinal_category'`, a single column (`_level_skforecast`) is created with integer values from 0 to n_series - 1. Then, the column is transformed into `pandas.category` dtype so that it can be used as a categorical variable.\n",
    "\n",
    "- `'onehot'`, a binary column is created for each series.\n",
    "\n",
    "- `None`, no encoding is performed (no column is created)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f6892272",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(255,145,0,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #ff9100; border-color: #ff9100; padding-left: 10px; padding-right: 10px\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#ff9100; border-color: #ff1744;\"></i>\n",
    "    <b style=\"color: #ff9100;\"> <span style=\"color: #ff9100;\">&#9888;</span> Warning</b>\n",
    "</p>\n",
    "\n",
    "<code>ForecasterRecursiveMultiSeries</code> class can use <code>encoding='ordinal_category'</code> for encoding time series identifiers. This approach creates a new column (<i>_level_skforecast</i>) of type pandas <code>category</code>. Consequently, the estimators must be able to handle categorical variables. If the estimators do not support categorical variables, the user should set the encoding to <code>'ordinal'</code> or <code>'onehot'</code> for compatibility.\n",
    "\n",
    "<p>Some examples of estimators that support categorical variables and how to enable them are:</p>\n",
    "\n",
    "<strong>HistGradientBoostingRegressor</strong> \n",
    "\n",
    "```python\n",
    "HistGradientBoostingRegressor(categorical_features=\"from_dtype\")\n",
    "```\n",
    "\n",
    "<strong>LightGBM</strong>\n",
    "\n",
    "<code>LGBMRegressor</code> does not allow configuration of categorical features during initialization, but rather in its <code>fit</code> method. Therefore, use Forecaster' argument <code>fit_kwargs = {'categorical_feature':'auto'}</code>. This is the default behavior of <code>LGBMRegressor</code> if no indication is given.\n",
    "\n",
    "<strong>XGBoost</strong>\n",
    "```python\n",
    "XGBRegressor(enable_categorical=True)\n",
    "```\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "a76479c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>_level_skforecast</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-04</th>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>8.253175</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-05</th>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-06</th>\n",
       "      <td>21.379238</td>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3 _level_skforecast\n",
       "2012-01-04  27.549099  22.777826   8.253175                 0\n",
       "2012-01-05  25.895533  27.549099  22.777826                 0\n",
       "2012-01-06  21.379238  25.895533  27.549099                 0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "lag_1                 float64\n",
      "lag_2                 float64\n",
      "lag_3                 float64\n",
      "_level_skforecast    category\n",
      "dtype: object\n",
      "\n",
      "_level_skforecast\n",
      "0    924\n",
      "1    924\n",
      "2    924\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Ordinal_category encoding\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = 'ordinal_category'\n",
    "             )\n",
    "\n",
    "X, y = forecaster.create_train_X_y(series=series_long_train, suppress_warnings=True)\n",
    "\n",
    "display(X.head(3))\n",
    "print(\"\")\n",
    "print(X.dtypes)\n",
    "print(\"\")\n",
    "print(X['_level_skforecast'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "627fa899",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭────────────────────────────────── InputTypeWarning ──────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Passing a DataFrame (either wide or long format) as `series` requires additional     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> internal transformations, which can increase computational time. It is recommended   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> to use a dictionary of pandas Series instead. For more details, see:                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> html#input-data                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.InputTypeWarning                                    <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:2349                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m InputTypeWarning \u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Passing a DataFrame (either wide or long format) as `series` requires additional     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m internal transformations, which can increase computational time. It is recommended   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m to use a dictionary of pandas Series instead. For more details, see:                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m html#input-data                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.InputTypeWarning                                    \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:2349                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>_level_skforecast</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-04</th>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>8.253175</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-05</th>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-06</th>\n",
       "      <td>21.379238</td>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3  _level_skforecast\n",
       "2012-01-04  27.549099  22.777826   8.253175                  0\n",
       "2012-01-05  25.895533  27.549099  22.777826                  0\n",
       "2012-01-06  21.379238  25.895533  27.549099                  0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "lag_1                float64\n",
      "lag_2                float64\n",
      "lag_3                float64\n",
      "_level_skforecast      int64\n",
      "dtype: object\n",
      "\n",
      "_level_skforecast\n",
      "0    924\n",
      "1    924\n",
      "2    924\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Ordinal encoding\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = 'ordinal'\n",
    "             )\n",
    "\n",
    "X, y = forecaster.create_train_X_y(series=series_long_train)\n",
    "\n",
    "display(X.head(3))\n",
    "print(\"\")\n",
    "print(X.dtypes)\n",
    "print(\"\")\n",
    "print(X['_level_skforecast'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "2bc2027d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "      <th>item_1</th>\n",
       "      <th>item_2</th>\n",
       "      <th>item_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-04</th>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>8.253175</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-05</th>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-06</th>\n",
       "      <td>21.379238</td>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3  item_1  item_2  item_3\n",
       "2012-01-04  27.549099  22.777826   8.253175       1       0       0\n",
       "2012-01-05  25.895533  27.549099  22.777826       1       0       0\n",
       "2012-01-06  21.379238  25.895533  27.549099       1       0       0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "lag_1     float64\n",
      "lag_2     float64\n",
      "lag_3     float64\n",
      "item_1      int64\n",
      "item_2      int64\n",
      "item_3      int64\n",
      "dtype: object\n",
      "\n",
      "item_1\n",
      "0    1848\n",
      "1     924\n",
      "Name: count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Onehot encoding (one column per series)\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = 'onehot'\n",
    "             )\n",
    "\n",
    "X, y = forecaster.create_train_X_y(series=series_long_train, suppress_warnings=True)\n",
    "\n",
    "display(X.head(3))\n",
    "print(\"\")\n",
    "print(X.dtypes)\n",
    "print(\"\")\n",
    "print(X['item_1'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "f5fd89b4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>lag_1</th>\n",
       "      <th>lag_2</th>\n",
       "      <th>lag_3</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2012-01-04</th>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "      <td>8.253175</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-05</th>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "      <td>22.777826</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2012-01-06</th>\n",
       "      <td>21.379238</td>\n",
       "      <td>25.895533</td>\n",
       "      <td>27.549099</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                lag_1      lag_2      lag_3\n",
       "2012-01-04  27.549099  22.777826   8.253175\n",
       "2012-01-05  25.895533  27.549099  22.777826\n",
       "2012-01-06  21.379238  25.895533  27.549099"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "lag_1    float64\n",
      "lag_2    float64\n",
      "lag_3    float64\n",
      "dtype: object\n"
     ]
    }
   ],
   "source": [
    "# Onehot encoding (one column per series)\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = None\n",
    "             )\n",
    "\n",
    "X, y = forecaster.create_train_X_y(series=series_long_train, suppress_warnings=True)\n",
    "\n",
    "display(X.head(3))\n",
    "print(\"\")\n",
    "print(X.dtypes)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a5c7dee",
   "metadata": {},
   "source": [
    "## Forecasting unknown series\n",
    "\n",
    "<code>ForecasterRecursiveMultiSeries</code> allows the prediction of unknown series (levels). If a series not seen during training is found during the prediction phase, the forecaster will encode the series according to the following rules:\n",
    "\n",
    "+ If `encoding` is `'onehot'`, all dummy columns are set to 0.\n",
    "\n",
    "+ If `encoding` is `'ordinal_category'` or `'ordinal'`, the value of the column `_level_skforecast` is set to `NaN`.\n",
    "\n",
    "Since the series was not present during training, the last window of the series must be provided when calling the `predict` method."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3660a60",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(255,145,0,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #ff9100; border-color: #ff9100; padding-left: 10px; padding-right: 10px\">\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#ff9100; border-color: #ff1744;\"></i>\n",
    "    <b style=\"color: #ff9100;\"> <span style=\"color: #ff9100;\">&#9888;</span> Warning</b>\n",
    "</p>\n",
    "\n",
    "Since the unknown series are encoded as NaN when the forecaster uses the <code>'ordinal_category'</code> or <code>'ordinal'</code> encoding, only estimators that can handle missing values can be used, otherwise an error will be raised.\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "bb9f3f0c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭────────────────────────────────── InputTypeWarning ──────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Passing a DataFrame (either wide or long format) as `series` requires additional     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> internal transformations, which can increase computational time. It is recommended   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> to use a dictionary of pandas Series instead. For more details, see:                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> html#input-data                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.InputTypeWarning                                    <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:2349                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m InputTypeWarning \u001b[0m\u001b[38;5;214m─────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Passing a DataFrame (either wide or long format) as `series` requires additional     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m internal transformations, which can increase computational time. It is recommended   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m to use a dictionary of pandas Series instead. For more details, see:                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m https://skforecast.org/latest/user_guides/independent-multi-time-series-forecasting. \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m html#input-data                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.InputTypeWarning                                    \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:2349                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=InputTypeWarning)                \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Series seen by during training: ['item_1', 'item_2', 'item_3']\n"
     ]
    }
   ],
   "source": [
    "# Forecaster trainied with series item_1, item_2 and item_3\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = 'ordinal'\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train)\n",
    "print(f\"Series seen by during training: {forecaster.series_names_in_}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2df8e8f3",
   "metadata": {},
   "source": [
    "The `last_window` argument is used to provide a pandas `DataFrame` containing the most recent observations of the target series required to generate the predictors. If no past observations are available, and the underlying estimator is capable of handling missing values, `last_window` can consist of a `DataFrame` filled with `NaNs`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "68d1f685",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>item_4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-13</th>\n",
       "      <td>23.4600</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-14</th>\n",
       "      <td>22.3587</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-15</th>\n",
       "      <td>29.3480</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             item_4\n",
       "2014-07-13  23.4600\n",
       "2014-07-14  22.3587\n",
       "2014-07-15  29.3480"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Forecasting a new series not seen in the training\n",
    "# ==============================================================================\n",
    "last_window_item_4 = pd.DataFrame(\n",
    "    data    = [23.46, 22.3587, 29.348],\n",
    "    columns = ['item_4'],\n",
    "    index   = pd.date_range(start=\"2014-07-13\", periods=3, freq=\"D\"),\n",
    ")\n",
    "last_window_item_4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "70f5c5a1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭──────────────────────────────── UnknownLevelWarning ─────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> `levels` {'item_4'} were not included in training. Unknown levels are encoded as     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> NaN, which may cause the prediction to fail if the estimator does not accept NaN     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> values.                                                                              <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.UnknownLevelWarning                                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:909                                                                          <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=UnknownLevelWarning)             <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m───────────────────────────────\u001b[0m\u001b[38;5;214m UnknownLevelWarning \u001b[0m\u001b[38;5;214m────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m `levels` {'item_4'} were not included in training. Unknown levels are encoded as     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m NaN, which may cause the prediction to fail if the estimator does not accept NaN     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m values.                                                                              \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.UnknownLevelWarning                                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:909                                                                          \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=UnknownLevelWarning)             \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_4</td>\n",
       "      <td>24.351416</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_4</td>\n",
       "      <td>25.779253</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-18</th>\n",
       "      <td>item_4</td>\n",
       "      <td>25.637366</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_4  24.351416\n",
       "2014-07-17  item_4  25.779253\n",
       "2014-07-18  item_4  25.637366"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Forecasting a new series not seen in the training\n",
    "# ==============================================================================\n",
    "forecaster.predict(\n",
    "    levels            = 'item_4', \n",
    "    steps             = 3, \n",
    "    last_window       = last_window_item_4,\n",
    "    suppress_warnings = False\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3a9b91e",
   "metadata": {},
   "source": [
    "If the forecaster's `encoding` parameter is set to `None`, the model does not take the series ID into account. As a result, it can generate forecasts for previously unseen series, as long as their corresponding `last_window` is provided."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "25bb07bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Forecaster trainied with series item_1, item_2 and item_3 without encoding\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = None\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train, suppress_warnings=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "f5119669",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_4</td>\n",
       "      <td>21.897883</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_4</td>\n",
       "      <td>19.992323</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-18</th>\n",
       "      <td>item_4</td>\n",
       "      <td>19.847593</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_4  21.897883\n",
       "2014-07-17  item_4  19.992323\n",
       "2014-07-18  item_4  19.847593"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Forecasting a new series not seen in the training\n",
    "# ==============================================================================\n",
    "forecaster.predict(\n",
    "    levels            = 'item_4', \n",
    "    steps             = 3, \n",
    "    last_window       = last_window_item_4,\n",
    "    suppress_warnings = False\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07b23d21",
   "metadata": {},
   "source": [
    "Forecast intervals for previously unseen series are also supported. In this case, a random sample of residuals—stored under the `_unknown_level` key—is drawn from the residuals of the known series. The reliability of the resulting intervals depends on the degree of similarity between the unknown series and those used during training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "a8a3e874",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Residuals for item_1: n=924\n",
      "Residuals for item_2: n=924\n",
      "Residuals for item_3: n=924\n",
      "Residuals for _unknown_level: n=2772\n"
     ]
    }
   ],
   "source": [
    "# Forecasting intervals for an unknown series\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 3,\n",
    "                 encoding  = 'ordinal'\n",
    "             )\n",
    "\n",
    "forecaster.fit(\n",
    "    series=series_long_train, store_in_sample_residuals=True, suppress_warnings=True\n",
    ")\n",
    "\n",
    "# Number of in-sample residuals by bin\n",
    "# ==============================================================================\n",
    "for k, v in forecaster.in_sample_residuals_.items():\n",
    "    print(f\"Residuals for {k}: n={len(v)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "3117302c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭──────────────────────────────── UnknownLevelWarning ─────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> `levels` {'item_4'} were not included in training. Unknown levels are encoded as     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> NaN, which may cause the prediction to fail if the estimator does not accept NaN     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> values.                                                                              <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.UnknownLevelWarning                                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:909                                                                          <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=UnknownLevelWarning)             <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m───────────────────────────────\u001b[0m\u001b[38;5;214m UnknownLevelWarning \u001b[0m\u001b[38;5;214m────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m `levels` {'item_4'} were not included in training. Unknown levels are encoded as     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m NaN, which may cause the prediction to fail if the estimator does not accept NaN     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m values.                                                                              \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.UnknownLevelWarning                                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:909                                                                          \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=UnknownLevelWarning)             \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╭──────────────────────────────── UnknownLevelWarning ─────────────────────────────────╮</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> `levels` {'item_4'} are not present in `forecaster.in_sample_residuals_by_bin_`,     <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> most likely because they were not present in the training data. A random sample of   <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> the residuals from other levels will be used. This can lead to inaccurate intervals  <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> for the unknown levels.                                                              <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>                                                                                      <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Category : skforecast.exceptions.UnknownLevelWarning                                 <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Location :                                                                           <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> tils.py:1275                                                                         <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span> Suppress : warnings.simplefilter('ignore', category=UnknownLevelWarning)             <span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">│</span>\n",
       "<span style=\"color: #ffaf00; text-decoration-color: #ffaf00\">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[38;5;214m╭─\u001b[0m\u001b[38;5;214m───────────────────────────────\u001b[0m\u001b[38;5;214m UnknownLevelWarning \u001b[0m\u001b[38;5;214m────────────────────────────────\u001b[0m\u001b[38;5;214m─╮\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m `levels` {'item_4'} are not present in `forecaster.in_sample_residuals_by_bin_`,     \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m most likely because they were not present in the training data. A random sample of   \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m the residuals from other levels will be used. This can lead to inaccurate intervals  \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m for the unknown levels.                                                              \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m                                                                                      \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Category : skforecast.exceptions.UnknownLevelWarning                                 \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Location :                                                                           \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m c:\\Users\\jaesc2\\Miniconda3\\envs\\skforecast_py12\\Lib\\site-packages\\skforecast\\utils\\u \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m tils.py:1275                                                                         \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m│\u001b[0m Suppress : warnings.simplefilter('ignore', category=UnknownLevelWarning)             \u001b[38;5;214m│\u001b[0m\n",
       "\u001b[38;5;214m╰──────────────────────────────────────────────────────────────────────────────────────╯\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "      <th>lower_bound</th>\n",
       "      <th>upper_bound</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_4</td>\n",
       "      <td>24.351416</td>\n",
       "      <td>20.331618</td>\n",
       "      <td>28.371213</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-17</th>\n",
       "      <td>item_4</td>\n",
       "      <td>25.779253</td>\n",
       "      <td>21.759456</td>\n",
       "      <td>29.799050</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-18</th>\n",
       "      <td>item_4</td>\n",
       "      <td>25.637366</td>\n",
       "      <td>21.617569</td>\n",
       "      <td>29.657163</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred  lower_bound  upper_bound\n",
       "2014-07-16  item_4  24.351416    20.331618    28.371213\n",
       "2014-07-17  item_4  25.779253    21.759456    29.799050\n",
       "2014-07-18  item_4  25.637366    21.617569    29.657163"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Forecasting intervals for an unknown series\n",
    "# ==============================================================================\n",
    "forecaster.predict_interval(\n",
    "    levels                  = 'item_4',\n",
    "    steps                   = 3,\n",
    "    last_window             = last_window_item_4,\n",
    "    use_in_sample_residuals = True,\n",
    "    suppress_warnings       = False\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "063cacb0",
   "metadata": {},
   "source": [
    "For the use of out-of-sample residuals (`use_in_sample_residuals = False`), the user can [provide the residuals](../user_guides/probabilistic-forecasting-bootstrapped-residuals.html#out-sample-residuals-non-conditioned-on-predicted-values) using the `set_out_sample_residuals` method and a random sample of residuals will be drawn to predict the unknown series."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "6ef846b0",
   "metadata": {},
   "source": [
    "## Weights in multi-series\n",
    "\n",
    "The weights are used to control the influence that each observation has on the training of the model. <code>ForecasterRecursiveMultiSeries</code> accepts two types of weights:\n",
    "\n",
    "+ `series_weights` controls the relative importance of each series. If a series has twice as much weight as the others, the observations of that series influence the training twice as much. The higher the weight of a series relative to the others, the more the model will focus on trying to learn that series.\n",
    "\n",
    "+ `weight_func` controls the relative importance of each observation according to its index value. For example, a function that assigns a lower weight to certain dates.\n",
    "\n",
    "If the two types of weights are indicated, they are **multiplied to create the final weights**. The resulting `sample_weight` cannot have negative values.\n",
    "\n",
    "<p style=\"text-align: center\">\n",
    "<img src=\"../img/forecaster_multi_series_sample_weight.png\" style=\"width: 900px\">\n",
    "<br>\n",
    "<font size=\"2.5\"> <i>Weights in multi-series.</i></font>\n",
    "</p>\n",
    "\n",
    "+ `series_weights` is a dict of the form `{'series_name': float}`. If a series is used during `fit` and is not present in `series_weights`, it will have a weight of 1.\n",
    "\n",
    "+ `weight_func` is a function that defines the individual weights of each sample **based on the index**. \n",
    "  \n",
    "    + If it is a `callable`, the same function will apply to all series. \n",
    "  \n",
    "    + If it is a `dict` of the form `{'series_name': callable}`, a different function can be used for each series. A weight of 1 is given to all series not present in `weight_func`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "d4966617",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>25.928016</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>11.429994</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_3</td>\n",
       "      <td>11.717830</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_1  25.928016\n",
       "2014-07-16  item_2  11.429994\n",
       "2014-07-16  item_3  11.717830"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Weights in Multi-Series\n",
    "# ==============================================================================\n",
    "def custom_weights(index):\n",
    "    \"\"\"\n",
    "    Return 0 if index is between '2013-01-01' and '2013-01-31', 1 otherwise.\n",
    "    \"\"\"\n",
    "    weights = np.where(\n",
    "                  (index >= '2013-01-01') & (index <= '2013-01-31'),\n",
    "                   0,\n",
    "                   1\n",
    "              )\n",
    "    \n",
    "    return weights\n",
    "\n",
    "\n",
    "# Series Weights, it is equivalent to {'item_2': 2.}\n",
    "series_weights = {\n",
    "    'item_1': 1., \n",
    "    'item_2': 2., \n",
    "    'item_3': 1.\n",
    "}\n",
    "\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator          = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags               = 24,\n",
    "                 window_features    = RollingFeatures(stats=['mean', 'mean'], window_sizes=[24, 48]),\n",
    "                 encoding           = 'ordinal',\n",
    "                 transformer_series = StandardScaler(),\n",
    "                 weight_func        = custom_weights,\n",
    "                 series_weights     = series_weights\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train, suppress_warnings=True)\n",
    "forecaster.predict(steps=24).head(3)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "9f7180da",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(255,145,0,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #ff9100; border-color: #ff9100; padding-left: 10px; padding-right: 10px\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#ff9100; border-color: #ff1744;\"></i>\n",
    "    <b style=\"color: #ff9100;\"> <span style=\"color: #ff9100;\">&#9888;</span> Warning</b>\n",
    "</p>\n",
    "\n",
    "The <code>weight_func</code> and <code>series_weights</code> arguments will be ignored if the estimator does not accept <code>sample_weight</code> in its <code>fit</code> method.\n",
    "\n",
    "</div>"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "3c410247",
   "metadata": {},
   "source": [
    "The source code of the `weight_func` added to the forecaster is stored in the argument `source_code_weight_func`. If `weight_func` is a `dict`, it will be a `dict` of the form `{'series_name': source_code_weight_func}` ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "fbe3c2a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "def custom_weights(index):\n",
      "    \"\"\"\n",
      "    Return 0 if index is between '2013-01-01' and '2013-01-31', 1 otherwise.\n",
      "    \"\"\"\n",
      "    weights = np.where(\n",
      "                  (index >= '2013-01-01') & (index <= '2013-01-31'),\n",
      "                   0,\n",
      "                   1\n",
      "              )\n",
      "\n",
      "    return weights\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Source code weight function\n",
    "# ==============================================================================\n",
    "print(forecaster.source_code_weight_func)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6600e6d8",
   "metadata": {},
   "source": [
    "## Differentiation\n",
    "\n",
    "Time series differentiation involves computing the differences between consecutive observations in the time series. When it comes to training forecasting models, differentiation offers the advantage of focusing on relative rates of change rather than directly attempting to model the absolute values. Once the predictions have been estimated, this transformation can be easily reversed to restore the values to their original scale.\n",
    "\n",
    "In the `ForecasterRecursiveMultiSeries` class, the `differentiation` argument can be:\n",
    "\n",
    "+ `int`: all series are differentiated `int` times.\n",
    "\n",
    "+ `dict`: a different order of differentiation can be specified for each series. For example, `differentiation = {'item_1': 1, 'item_2': 2, 'item_3': None, '_unknown_level': 1}`. The `_unknown_level` key is used to differentiate the unknown series when predicting.\n",
    "\n",
    "When using a `dict`, the value needed to include in the `differentiation` argument of a `cv` (e.g. `TimeSeriesFold` for [backtesting](../user_guides/backtesting.html)) object is the maximum differentiation order of all series. This value is available in the `differentiation_max` attribute."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7745863",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,191,191,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00bfa5; border-color: #00bfa5; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00bfa5;\"></i>\n",
    "    <b style=\"color: #00bfa5;\">&#128161 Tip</b>\n",
    "</p>\n",
    "\n",
    "To learn more about modeling time series differentiation, visit our example: <a href=\"https://www.cienciadedatos.net/documentos/py49-modelling-time-series-trend-with-tree-based-models.html\">Modelling time series trend with tree based models</a>.\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "9ad76b81",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <style>\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a {\n",
       "            font-family: 'Arial', sans-serif;\n",
       "            font-size: 0.9em;\n",
       "            color: #333333;\n",
       "            border: 1px solid #ddd;\n",
       "            background-color: #f0f8ff;\n",
       "            padding: 5px 15px;\n",
       "            border-radius: 8px;\n",
       "            max-width: 600px;\n",
       "            #margin: auto;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a h2 {\n",
       "            font-size: 1.5em;\n",
       "            color: #222222;\n",
       "            border-bottom: 2px solid #ddd;\n",
       "            padding-bottom: 5px;\n",
       "            margin-bottom: 15px;\n",
       "            margin-top: 5px;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a details {\n",
       "            margin: 10px 0;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a summary {\n",
       "            font-weight: bold;\n",
       "            font-size: 1.1em;\n",
       "            color: #000000;\n",
       "            cursor: pointer;\n",
       "            margin-bottom: 5px;\n",
       "            background-color: #b3dbfd;\n",
       "            padding: 5px;\n",
       "            border-radius: 5px;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a summary:hover {\n",
       "            color: #000000;\n",
       "            background-color: #e0e0e0;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a ul {\n",
       "            font-family: 'Courier New', monospace;\n",
       "            list-style-type: none;\n",
       "            padding-left: 20px;\n",
       "            margin: 10px 0;\n",
       "            line-height: normal;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a li {\n",
       "            margin: 5px 0;\n",
       "            font-family: 'Courier New', monospace;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a li strong {\n",
       "            font-weight: bold;\n",
       "            color: #444444;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a li::before {\n",
       "            content: \"- \";\n",
       "            color: #666666;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a a {\n",
       "            color: #001633;\n",
       "            text-decoration: none;\n",
       "        }\n",
       "        .container-c7a56d08dbdf4192acaf6b016692371a a:hover {\n",
       "            color: #359ccb; \n",
       "        }\n",
       "    </style>\n",
       "    \n",
       "        <div class=\"container-c7a56d08dbdf4192acaf6b016692371a\">\n",
       "            <p style=\"font-size: 1.5em; font-weight: bold; margin-block-start: 0.83em; margin-block-end: 0.83em;\">ForecasterRecursiveMultiSeries</p>\n",
       "            <details open>\n",
       "                <summary>General Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Estimator:</strong> LGBMRegressor</li>\n",
       "                    <li><strong>Lags:</strong> [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]</li>\n",
       "                    <li><strong>Window features:</strong> ['roll_mean_24', 'roll_mean_48']</li>\n",
       "                    <li><strong>Window size:</strong> 49</li>\n",
       "                    <li><strong>Series encoding:</strong> ordinal</li>\n",
       "                    <li><strong>Exogenous included:</strong> False</li>\n",
       "                    <li><strong>Weight function included:</strong> False</li>\n",
       "                    <li><strong>Series weights:</strong> None</li>\n",
       "                    <li><strong>Differentiation order:</strong> 1</li>\n",
       "                    <li><strong>Creation date:</strong> 2025-11-26 15:16:59</li>\n",
       "                    <li><strong>Last fit date:</strong> 2025-11-26 15:16:59</li>\n",
       "                    <li><strong>Skforecast version:</strong> 0.19.0</li>\n",
       "                    <li><strong>Python version:</strong> 3.12.11</li>\n",
       "                    <li><strong>Forecaster id:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Exogenous Variables</summary>\n",
       "                <ul>\n",
       "                    None\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Data Transformations</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Transformer for series:</strong> None</li>\n",
       "                    <li><strong>Transformer for exog:</strong> None</li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Training Information</summary>\n",
       "                <ul>\n",
       "                    <li><strong>Series names (levels):</strong> item_1, item_2, item_3</li>\n",
       "                    <li><strong>Training range:</strong> 'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'], 'item_3': ['2012-01-01', '2014-07-15']</li>\n",
       "                    <li><strong>Training index type:</strong> DatetimeIndex</li>\n",
       "                    <li><strong>Training index frequency:</strong> <Day></li>\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Estimator Parameters</summary>\n",
       "                <ul>\n",
       "                    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0, 'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1, 'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0, 'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None, 'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0, 'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <details>\n",
       "                <summary>Fit Kwargs</summary>\n",
       "                <ul>\n",
       "                    {}\n",
       "                </ul>\n",
       "            </details>\n",
       "            <p>\n",
       "                <a href=\"https://skforecast.org/0.19.0/api/forecasterrecursivemultiseries.html\">&#128712 <strong>API Reference</strong></a>\n",
       "                &nbsp;&nbsp;\n",
       "                <a href=\"https://skforecast.org/0.19.0/user_guides/independent-multi-time-series-forecasting.html\">&#128462 <strong>User Guide</strong></a>\n",
       "            </p>\n",
       "        </div>\n",
       "        "
      ],
      "text/plain": [
       "============================== \n",
       "ForecasterRecursiveMultiSeries \n",
       "============================== \n",
       "Estimator: LGBMRegressor \n",
       "Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] \n",
       "Window features: ['roll_mean_24', 'roll_mean_48'] \n",
       "Window size: 49 \n",
       "Series encoding: ordinal \n",
       "Series names (levels): item_1, item_2, item_3 \n",
       "Exogenous included: False \n",
       "Exogenous names: None \n",
       "Transformer for series: None \n",
       "Transformer for exog: None \n",
       "Weight function included: False \n",
       "Series weights: None \n",
       "Differentiation order: 1 \n",
       "Training range: \n",
       "    'item_1': ['2012-01-01', '2014-07-15'], 'item_2': ['2012-01-01', '2014-07-15'],\n",
       "    'item_3': ['2012-01-01', '2014-07-15'] \n",
       "Training index type: DatetimeIndex \n",
       "Training index frequency: <Day> \n",
       "Estimator parameters: \n",
       "    {'boosting_type': 'gbdt', 'class_weight': None, 'colsample_bytree': 1.0,\n",
       "    'importance_type': 'split', 'learning_rate': 0.1, 'max_depth': -1,\n",
       "    'min_child_samples': 20, 'min_child_weight': 0.001, 'min_split_gain': 0.0,\n",
       "    'n_estimators': 100, 'n_jobs': None, 'num_leaves': 31, 'objective': None,\n",
       "    'random_state': 123, 'reg_alpha': 0.0, 'reg_lambda': 0.0, 'subsample': 1.0,\n",
       "    'subsample_for_bin': 200000, 'subsample_freq': 0, 'verbose': -1} \n",
       "fit_kwargs: {} \n",
       "Creation date: 2025-11-26 15:16:59 \n",
       "Last fit date: 2025-11-26 15:16:59 \n",
       "Skforecast version: 0.19.0 \n",
       "Python version: 3.12.11 \n",
       "Forecaster id: None "
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create and fit forecaster\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator       = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags            = 24,\n",
    "                 window_features = RollingFeatures(stats=['mean', 'mean'], window_sizes=[24, 48]),\n",
    "                 differentiation = 1  # Same as {'item_1': 1, 'item_2': 1, 'item_3': 1, '_unknown_level': 1}\n",
    "             )\n",
    "\n",
    "forecaster.fit(series=series_long_train, suppress_warnings=True)\n",
    "forecaster"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f85ede6f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>level</th>\n",
       "      <th>pred</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_1</td>\n",
       "      <td>26.332222</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_2</td>\n",
       "      <td>10.707126</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2014-07-16</th>\n",
       "      <td>item_3</td>\n",
       "      <td>10.825073</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             level       pred\n",
       "2014-07-16  item_1  26.332222\n",
       "2014-07-16  item_2  10.707126\n",
       "2014-07-16  item_3  10.825073"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Predict\n",
    "# ==============================================================================\n",
    "predictions = forecaster.predict(steps=24)\n",
    "predictions.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c362ade2",
   "metadata": {},
   "source": [
    "## Probabilistic forecasting\n",
    "\n",
    "**Skforecast** allows to apply all its implemented probabilistic forecasting methods (**bootstrapping**, **conformal prediction** and **quantile regression**) to global models. This means that the model is trained with all the available time series and the forecast is made for all the time series.\n",
    "\n",
    "Visit [Probabilistic forecasting: Global Models](../user_guides/probabilistic-forecasting-global-models.html) for more information."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4cb7999f",
   "metadata": {},
   "source": [
    "## Feature selection in multi-series\n",
    "\n",
    "Feature selection is the process of **selecting a subset of relevant features** (variables, predictors) for use in model construction. Feature selection techniques are used for several reasons: to simplify models to make them easier to interpret, to reduce training time, to avoid the curse of dimensionality, to improve generalization by reducing overfitting (formally, variance reduction), and others.\n",
    "\n",
    "**Skforecast** is compatible with the [feature selection methods implemented in the scikit-learn](https://scikit-learn.org/stable/modules/feature_selection.html) library. Visit [Global Forecasting Models: Feature Selection](../user_guides/feature-selection.html#global-forecasting-models-feature-selection) for more information."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "31b0c86d",
   "metadata": {},
   "source": [
    "## Compare multiple metrics\n",
    "\n",
    "The functions `backtesting_forecaster_multiseries`, `grid_search_forecaster_multiseries`, `random_search_forecaster_multiseries`, and `bayesian_search_forecaster_multiseries` support the evaluation of **multiple metrics** by passing a `list` of metric functions. This list can include both built-in metrics (e.g. `mean_squared_error`, `mean_absolute_error`) and custom-defined ones.\n",
    "\n",
    "When multiple metrics are provided, the **first metric in the list** and the **first aggregation method** are used to select the best model."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75001fca",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\" name=\"html-admonition\" style=\"background: rgba(0,191,191,.1); padding-top: 0px; padding-bottom: 6px; border-radius: 8px; border-left: 8px solid #00bfa5; border-color: #00bfa5; padding-left: 10px; padding-right: 10px;\">\n",
    "\n",
    "<p class=\"title\">\n",
    "    <i style=\"font-size: 18px; color:#00bfa5;\"></i>\n",
    "    <b style=\"color: #00bfa5;\">&#128161 Tip</b>\n",
    "</p>\n",
    "\n",
    "More information about <b>time series forecasting metrics</b> can be found in the <a href=\"../user_guides/metrics.html\">Metrics</a> guide.\n",
    "\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "9b5c77b3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "0bfccdb608cc49319d78c5e2adaec5cc",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "lags grid:   0%|          | 0/2 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c408ccf14e914662b4992dd4bb287c3b",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "params grid:   0%|          | 0/4 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "`Forecaster` refitted using the best-found lags and parameters, and the whole data set: \n",
      "  Lags: [ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24\n",
      " 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48] \n",
      "  Parameters: {'max_depth': 7, 'n_estimators': 20}\n",
      "  Backtesting metric: 2.288448178505924\n",
      "  Levels: ['item_1', 'item_2', 'item_3']\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>levels</th>\n",
       "      <th>lags</th>\n",
       "      <th>lags_label</th>\n",
       "      <th>params</th>\n",
       "      <th>mean_absolute_error__weighted_average</th>\n",
       "      <th>mean_absolute_error__average</th>\n",
       "      <th>mean_absolute_error__pooling</th>\n",
       "      <th>custom_metric__weighted_average</th>\n",
       "      <th>custom_metric__average</th>\n",
       "      <th>custom_metric__pooling</th>\n",
       "      <th>mean_squared_error__weighted_average</th>\n",
       "      <th>mean_squared_error__average</th>\n",
       "      <th>mean_squared_error__pooling</th>\n",
       "      <th>max_depth</th>\n",
       "      <th>n_estimators</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'max_depth': 7, 'n_estimators': 20}</td>\n",
       "      <td>2.288448</td>\n",
       "      <td>2.288448</td>\n",
       "      <td>2.288448</td>\n",
       "      <td>2.314922</td>\n",
       "      <td>2.314922</td>\n",
       "      <td>2.314922</td>\n",
       "      <td>9.462712</td>\n",
       "      <td>9.462712</td>\n",
       "      <td>9.462712</td>\n",
       "      <td>7</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'max_depth': 7, 'n_estimators': 20}</td>\n",
       "      <td>2.357734</td>\n",
       "      <td>2.357734</td>\n",
       "      <td>2.357734</td>\n",
       "      <td>2.306112</td>\n",
       "      <td>2.306112</td>\n",
       "      <td>2.306112</td>\n",
       "      <td>10.121310</td>\n",
       "      <td>10.121310</td>\n",
       "      <td>10.121310</td>\n",
       "      <td>7</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'max_depth': 3, 'n_estimators': 20}</td>\n",
       "      <td>2.377537</td>\n",
       "      <td>2.377537</td>\n",
       "      <td>2.377537</td>\n",
       "      <td>2.302790</td>\n",
       "      <td>2.302790</td>\n",
       "      <td>2.302790</td>\n",
       "      <td>10.179578</td>\n",
       "      <td>10.179578</td>\n",
       "      <td>10.179578</td>\n",
       "      <td>3</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[item_1, item_2, item_3]</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...</td>\n",
       "      <td>{'max_depth': 3, 'n_estimators': 20}</td>\n",
       "      <td>2.474797</td>\n",
       "      <td>2.474797</td>\n",
       "      <td>2.474797</td>\n",
       "      <td>2.365732</td>\n",
       "      <td>2.365732</td>\n",
       "      <td>2.365732</td>\n",
       "      <td>10.708651</td>\n",
       "      <td>10.708651</td>\n",
       "      <td>10.708651</td>\n",
       "      <td>3</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                     levels  \\\n",
       "0  [item_1, item_2, item_3]   \n",
       "1  [item_1, item_2, item_3]   \n",
       "2  [item_1, item_2, item_3]   \n",
       "3  [item_1, item_2, item_3]   \n",
       "\n",
       "                                                lags  \\\n",
       "0  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "1  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "2  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "3  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "\n",
       "                                          lags_label  \\\n",
       "0  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "1  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "2  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "3  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...   \n",
       "\n",
       "                                 params  \\\n",
       "0  {'max_depth': 7, 'n_estimators': 20}   \n",
       "1  {'max_depth': 7, 'n_estimators': 20}   \n",
       "2  {'max_depth': 3, 'n_estimators': 20}   \n",
       "3  {'max_depth': 3, 'n_estimators': 20}   \n",
       "\n",
       "   mean_absolute_error__weighted_average  mean_absolute_error__average  \\\n",
       "0                               2.288448                      2.288448   \n",
       "1                               2.357734                      2.357734   \n",
       "2                               2.377537                      2.377537   \n",
       "3                               2.474797                      2.474797   \n",
       "\n",
       "   mean_absolute_error__pooling  custom_metric__weighted_average  \\\n",
       "0                      2.288448                         2.314922   \n",
       "1                      2.357734                         2.306112   \n",
       "2                      2.377537                         2.302790   \n",
       "3                      2.474797                         2.365732   \n",
       "\n",
       "   custom_metric__average  custom_metric__pooling  \\\n",
       "0                2.314922                2.314922   \n",
       "1                2.306112                2.306112   \n",
       "2                2.302790                2.302790   \n",
       "3                2.365732                2.365732   \n",
       "\n",
       "   mean_squared_error__weighted_average  mean_squared_error__average  \\\n",
       "0                              9.462712                     9.462712   \n",
       "1                             10.121310                    10.121310   \n",
       "2                             10.179578                    10.179578   \n",
       "3                             10.708651                    10.708651   \n",
       "\n",
       "   mean_squared_error__pooling  max_depth  n_estimators  \n",
       "0                     9.462712          7            20  \n",
       "1                    10.121310          7            20  \n",
       "2                    10.179578          3            20  \n",
       "3                    10.708651          3            20  "
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Grid search Multi-Series with multiple metrics\n",
    "# ==============================================================================\n",
    "forecaster = ForecasterRecursiveMultiSeries(\n",
    "                 estimator = LGBMRegressor(random_state=123, verbose=-1),\n",
    "                 lags      = 24,\n",
    "                 encoding  = 'ordinal'\n",
    "             )\n",
    "\n",
    "\n",
    "def custom_metric(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    Calculate the mean absolute error using only the predicted values of the last\n",
    "    3 months of the year.\n",
    "    \"\"\"\n",
    "    mask = y_true.index.month.isin([10, 11, 12])\n",
    "    metric = mean_absolute_error(y_true[mask], y_pred[mask])\n",
    "    \n",
    "    return metric\n",
    "\n",
    "\n",
    "lags_grid = [24, 48]\n",
    "param_grid = {\n",
    "    'n_estimators': [10, 20],\n",
    "    'max_depth': [3, 7]\n",
    "}\n",
    "\n",
    "cv = TimeSeriesFold(\n",
    "         steps              = 24,\n",
    "         initial_train_size = '2014-07-15 23:59:00',\n",
    "         refit              = True,\n",
    "     )\n",
    "\n",
    "results = grid_search_forecaster_multiseries(\n",
    "              forecaster        = forecaster,\n",
    "              series            = series_long,\n",
    "              exog              = None,\n",
    "              lags_grid         = lags_grid,\n",
    "              param_grid        = param_grid,\n",
    "              cv                = cv,\n",
    "              levels            = None,\n",
    "              metric            = [mean_absolute_error, custom_metric, 'mean_squared_error'],\n",
    "              aggregate_metric  = ['weighted_average', 'average', 'pooling'],\n",
    "              suppress_warnings = True\n",
    "          )\n",
    "\n",
    "results.head(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4483ec6",
   "metadata": {},
   "source": [
    "## Training and prediction matrices\n",
    "\n",
    "While the primary goal of building forecasting models is to predict future values, it is equally important to evaluate if the model is effectively learning from the training data. Analyzing predictions on the training data or exploring the prediction matrices is crucial for assessing model performance and understanding areas for optimization. This process can help identify issues like overfitting or underfitting, as well as provide deeper insights into the model’s decision-making process. Check the [How to Extract Training and Prediction Matrices](../user_guides/training-and-prediction-matrices.html) user guide for more information."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "skforecast_py12",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "184.087px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
